大数据BI可视化(Echarts组件)项目开发-熟悉结合Vue开发图表组件7.0附带1/6商家销售统计(横向柱状图)

一.创建项目

创建

1.npm install -g @vue/cli

vue create vision

4.版本

5.是否使用历史路由

6.CSS预处理

7.ES标准配置

8.啥时候es标准提示-保存文件后

9.将配置文件放入单独文件中处理

10.需要保留新建项目以上设置

11.选择"Use PNPM"或者"Use NPM"

12.创建

13访问

删除无用项目代码

1.App.vue

静态资源引入

项目的基本配置

javascript 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true
})
module.exports = {
  devServer: {
    port: 8888,
    open: true
  }
}

全局Echarts对象挂载

<!-- 一旦通过script标签引入的echarts.js文件后,window.echarts -->

<script src="static/lib/echarts.min.js"></script>

// 将全局的echarts对象挂载到vue的原型对象上

// 别的组件使用 this.$echarts

Vue.prototype.$echarts = window.echarts

axios的封装与挂载

1.npm install axios

2.调用

javascript 复制代码
// eslint-disable-next-line no-unused-vars
import axios from 'axios'
// 请求基准路径的配置
axios.defaults.baseURL = 'http://127.0.0.1:8888/api'
// 将axios挂载到vue的原型对象上
// 在别的组件 this.$http
Vue.prototype.$http = axios

二.单独图表组件开发

模板

V1

html 复制代码
 <template>
    <div >
    </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  methods: {},
  components: {
  }
}
</script>

  <style lang=less scoped>
</style>

商家销售统计(横向柱状图)

1.组件结构的设计

1.1创建SellerPage.vue
html 复制代码
<!--
    针对 /sellerpage  这条路径而显示出来的
    在这个组件中,通过子组件注册方式,显示出seller.vue这个组件
 -->
 <template>
    <div >
    </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  methods: {},
  components: {
  }
}
</script>

  <style lang=less scoped>
</style>
1.2Seller.vue 呈现图表组件
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
    }
  },
  mounted () {
  },
  // 生命周期
  destroyed () {
  },
  methods: {

  }
}
</script>

  <style lang=less scoped>
  </style>
1.3router 注入SellerPage文件,路由设置;
javascript 复制代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import SellerPage from '@/views/SellerPage.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/sellerpage',
    component: SellerPage
  }
]

const router = new VueRouter({
  routes
})

export default router
1.4app.vue 声明路由占位符
html 复制代码
<template>
  <div id="app">

    <!-- 路由占位符 -->
    <router-view></router-view>
  </div>
</template>

<style lang="less">
</style>
1.5访问sellerpage.vue内容
1.6通过sellerpage文件访问seller文件
html 复制代码
<!--
    针对 /sellerpage  这条路径而显示出来的
    在这个组件中,通过子组件注册方式,显示出seller.vue这个组件
 -->
 <template>
    <div>
        <seller></seller>
    </div>
</template>

<script>
// eslint-disable-next-line no-unused-vars
import Seller from '@/components/Seller.vue'
export default {
  data () {
    return {}
  },
  methods: {},
  components: {
    // eslint-disable-next-line vue/no-unused-components
    seller: Seller
  }
}
</script>

  <style lang=less scoped>
</style>

2.布局结构的设计

2.1seller文件设置样式
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
    }
  },
  mounted () {
  },
  // 生命周期
  destroyed () {
  },
  methods: {

  }
}
</script>

  <style lang=less scoped>
  </style>
2.2sellerpage文件设置样式
html 复制代码
<!--
    针对 /sellerpage  这条路径而显示出来的
    在这个组件中,通过子组件注册方式,显示出seller.vue这个组件
 -->
 <template>
    <div class="com-page">
        <seller></seller>
    </div>
</template>

<script>
// eslint-disable-next-line no-unused-vars
import Seller from '@/components/Seller.vue'
export default {
  data () {
    return {}
  },
  methods: {},
  components: {
    // eslint-disable-next-line vue/no-unused-components
    seller: Seller
  }
}
</script>

  <style lang=less scoped>
</style>
2.3在asset中编写css文件
css 复制代码
html,body,#app {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    overflow: hidden;
}

.com-page{
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.com-container{
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.com-chart{
    width: 100%;
    height: 100%;
    overflow: hidden;
}
3.4在main.js引入全局样式
javascript 复制代码
// 引入全局的样式文件
import './assets/css/global.less'
3.5查看

3.图表基本功能的实现

3.1initChart 初始化echartsinstance对象
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null
    }
  },
  mounted () {
    this.initChart()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    getData () {},
    // 更新图表
    updatechart () {}
  }
}
</script>

  <style lang=less scoped>
  </style>
3.2getData获取数据
3.2.1获取数据
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const ret = await this.$http.get('seller')
      console.log(ret)
    },
    // 更新图表
    updatechart () {}
  }
}
</script>

  <style lang=less scoped>
  </style>
3.2.2提取data数据
javascript 复制代码
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      console.log(ret)
    },
3.3updateChart跟新图表显示
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null // 服务器返回的数据
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 调用updatechart
      this.updatechart()
    },
    // 更新图表
    updatechart () {
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = this.allData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = this.allData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>

4.动态刷新的实现

4.1数据处理
4.1.1数据从小到大排序
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null // 服务器返回的数据
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 调用updatechart
      this.updatechart()
    },
    // 更新图表
    updatechart () {
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = this.allData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = this.allData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
4.1.2每五个元素一页
currentPage 第几页
totaPage 总共几页
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
4.2启动和停止的时机
4.2.1获取数据之后
启动定时器
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
    },
    startInterval () {
      setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
关闭定时器
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
4.2.2鼠标移出图表时启动定时器
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
      // 对图表对象进行鼠标事件的监听
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
4.3边界值的处理
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
      // 对图表对象进行鼠标事件的监听
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>

5.UI调整

5.1主题使用
html 复制代码
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <!-- 一旦通过script标签引入的echarts.js文件后,window.echarts -->
    <script src="static/lib/echarts.min.js"></script>
    <!-- 引入主题的js文件 -->
    <script src="static/theme/chalk.js"></script>    
  </body>
</html>
html 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref, 'chalk')
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        series: [
          {
            type: 'bar',
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(option)
      // 对图表对象进行鼠标事件的监听
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
5.2图表的圆角
css 复制代码
html,body,#app {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    overflow: hidden;
}

.com-page{
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.com-container{
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.com-chart{
    width: 100%;
    height: 100%;
    overflow: hidden;
}

//图表圆角
canvas {
    border-radius: 20px;
  }
5.3图表的标题
javascript 复制代码
        title: {
          text: '▎商家销售统计',
          textStyle: {
            fontSize: 66
          },
5.4坐标轴的位置
javascript 复制代码
        grid: {
          top: '20%',
          left: '3%',
          right: '6%',
          bottom: '3%',
          containLabel: true // 距离是包含坐标轴上的文字
        },
5.5柱状图条目
  • 宽度
javascript 复制代码
        series: [
          {
            type: 'bar',
            data: sellerValue,
            barWidth: 66
          }
        ]
文字
javascript 复制代码
            label: {
              show: true,
              position: 'right',
              textStyle: {
                color: 'white'
              }
            }
右边圆角
javascript 复制代码
            itemStyle: {
              barBorderRadius: [0, 33, 33, 0]
            }
颜色渐变
javascript 复制代码
              // 指明颜色渐变的方向
              // 指明不同百分比之下颜色的值
              color: new this.$echarts.graphic.LinearGradient(0, 0, 1, 0, [
                // 百分之0状态之下的颜色值
                {
                  offset: 0,
                  color: '#5052EE'
                },
                // 百分之100状态之下的颜色值
                {
                  offset: 1,
                  color: '#AB6EE5'
                }
              ])
背景
javascript 复制代码
        tooltip: {
          trigger: 'axis', // 鼠标移动坐标轴触发
          axisPointer: { // 触发的样式
            type: 'line', // 类型
            z: 0, // 层级
            lineStyle: {
              width: 66, // 宽度
              color: '#2D3443' // 颜色
            }
          }
        },

6.拆分图表的option

保留拆分前代码
javascript 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref, 'chalk')
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const option = {
        title: {
          text: '▎商家销售统计',
          textStyle: {
            fontSize: 66
          },
          left: 20,
          top: 20
        },
        grid: {
          top: '20%',
          left: '3%',
          right: '6%',
          bottom: '3%',
          containLabel: true // 距离是包含坐标轴上的文字
        },
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: sellerNames
        },
        tooltip: {
          trigger: 'axis', // 鼠标移动坐标轴触发
          axisPointer: { // 触发的样式
            type: 'line', // 类型
            z: 0, // 层级
            lineStyle: {
              width: 66,
              color: '#2D3443' // 颜色
            }
          }
        },
        series: [
          {
            type: 'bar',
            data: sellerValue,
            barWidth: 66,
            label: {
              show: true,
              position: 'right',
              textStyle: {
                color: 'white'
              }
            },
            itemStyle: {
              barBorderRadius: [0, 33, 33, 0],
              // 指明颜色渐变的方向
              // 指明不同百分比之下颜色的值
              color: new this.$echarts.graphic.LinearGradient(0, 0, 1, 0, [
                // 百分之0状态之下的颜色值
                {
                  offset: 0,
                  color: '#5052EE'
                },
                // 百分之100状态之下的颜色值
                {
                  offset: 1,
                  color: '#AB6EE5'
                }
              ])
            }
          }
        ]
      }
      this.chartInstance.setOption(option)
      // 对图表对象进行鼠标事件的监听
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    }
  }
}
</script>

  <style lang=less scoped>
  </style>
6.1初始化配置initOption
javascript 复制代码
      // 对图表初始化配置的控制
      const initOption = {
        title: {
          text: '▎商家销售统计',
          textStyle: {
            fontSize: 66
          },
          left: 20,
          top: 20
        },
        grid: {
          top: '20%',
          left: '3%',
          right: '6%',
          bottom: '3%',
          containLabel: true // 距离是包含坐标轴上的文字
        },
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category'
        },
        tooltip: {
          trigger: 'axis', // 鼠标移动坐标轴触发
          axisPointer: { // 触发的样式
            type: 'line', // 类型
            z: 0, // 层级
            lineStyle: {
              width: 66,
              color: '#2D3443' // 颜色
            }
          }
        },
        series: [
          {
            type: 'bar',
            barWidth: 66,
            label: {
              show: true,
              position: 'right',
              textStyle: {
                color: 'white'
              }
            },
            itemStyle: {
              barBorderRadius: [0, 33, 33, 0],
              // 指明颜色渐变的方向
              // 指明不同百分比之下颜色的值
              color: new this.$echarts.graphic.LinearGradient(0, 0, 1, 0, [
                // 百分之0状态之下的颜色值
                {
                  offset: 0,
                  color: '#5052EE'
                },
                // 百分之100状态之下的颜色值
                {
                  offset: 1,
                  color: '#AB6EE5'
                }
              ])
            }
          }
        ]
      }
      this.chartInstance.setOption(initOption)
6.2获取数据之后的配置dataOption
javascript 复制代码
      const dataOption = {
        yAxis: {
          data: sellerNames
        },
        series: [
          {
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(dataOption)
6.3分辨率适配的配置adapterOption
  • 监听窗口大小变化的事件
  • 获取图表容器的宽度
  • 设置新的option
    • 标题文字大小
    • 柱的宽度
    • 柱的圆角
    • 阴影背景宽度
  • 图表实例对象resize

取消监听

javascript 复制代码
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
    // 在组件销毁的时候, 需要将监听器取消掉
    window.removeEventListener('resize', this.screenAdapter)
  },

代码

javascript 复制代码
  mounted () {
    this.initChart()
    this.getData()
    // 窗口发生变动自动调用screenAdapter方法
    window.addEventListener('resize', this.screenAdapter)
    // 在页面加载完成的时候, 主动进行屏幕的适配
    this.screenAdapter()
  },
javascript 复制代码
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
    // 在组件销毁的时候, 需要将监听器取消掉
    window.removeEventListener('resize', this.screenAdapter)
  },
javascript 复制代码
    // 当浏览器的大小发生变化的时候, 会调用的方法, 来完成屏幕的适配
    screenAdapter () {
      // console.log(this.$refs.seller_ref.offsetWidth)
      const titleFontSize = this.$refs.seller_ref.offsetWidth / 100 * 3.6
      // 和分辨率大小相关的配置项
      const adapterOption = {
        title: {
          textStyle: {
            fontSize: titleFontSize
          }
        },
        tooltip: {
          axisPointer: {
            lineStyle: {
              width: titleFontSize
            }
          }
        },
        series: [
          {
            barWidth: titleFontSize,
            itemStyle: {
              barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0]
            }
          }
        ]
      }
      this.chartInstance.setOption(adapterOption)
      // 手动的调用图表对象的resize 才能产生效果
      this.chartInstance.resize()
    }
拆分后代码
javascript 复制代码
<!-- eslint-disable vue/multi-word-component-names -->
<!--  商家销量统计的横向柱状图-->
<template>
    <div class="com-container">
      <div class="com-chart" ref="seller_ref"></div>
    </div>
  </template>

<script>
export default {

  data () {
    return {
      chartInstance: null,
      allData: null, // 服务器返回的数据
      currentPage: 1, // 当前显示的页数
      totalPage: 0 // 一共有多少页
    }
  },
  mounted () {
    this.initChart()
    this.getData()
    // 窗口发生变动自动调用screenAdapter方法
    window.addEventListener('resize', this.screenAdapter)
    // 在页面加载完成的时候, 主动进行屏幕的适配
    this.screenAdapter()
  },
  // 生命周期
  destroyed () {
    clearInterval(this.timerId)
    // 在组件销毁的时候, 需要将监听器取消掉
    window.removeEventListener('resize', this.screenAdapter)
  },
  methods: {
    // 初始化echartsinstance对象
    initChart () {
      this.chartInstance = this.$echarts.init(this.$refs.seller_ref, 'chalk')
      // 对图表初始化配置的控制
      const initOption = {
        title: {
          text: '▎商家销售统计',
          left: 20,
          top: 20
        },
        grid: {
          top: '20%',
          left: '3%',
          right: '6%',
          bottom: '3%',
          containLabel: true // 距离是包含坐标轴上的文字
        },
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category'
        },
        tooltip: {
          trigger: 'axis', // 鼠标移动坐标轴触发
          axisPointer: { // 触发的样式
            type: 'line', // 类型
            z: 0, // 层级
            lineStyle: {
              color: '#2D3443' // 颜色
            }
          }
        },
        series: [
          {
            type: 'bar',
            label: {
              show: true,
              position: 'right',
              textStyle: {
                color: 'white'
              }
            },
            itemStyle: {
              // 指明颜色渐变的方向
              // 指明不同百分比之下颜色的值
              color: new this.$echarts.graphic.LinearGradient(0, 0, 1, 0, [
                // 百分之0状态之下的颜色值
                {
                  offset: 0,
                  color: '#5052EE'
                },
                // 百分之100状态之下的颜色值
                {
                  offset: 1,
                  color: '#AB6EE5'
                }
              ])
            }
          }
        ]
      }
      this.chartInstance.setOption(initOption)
    },
    // 获取数据
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      // console.log(ret)
      this.allData = ret
      // 对数据排序
      this.allData.sort((a, b) => {
        return a.value - b.value // 从小到大
      })
      // 每5个元素显示一页
      this.totalPage = this.allData.length % 5 === 0 ? this.allData.length / 5 : this.allData.length / 5 + 1
      // 调用updatechart
      this.updatechart()
      // 启动定时器
      this.startInterval()
    },
    // 更新图表
    updatechart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      // eslint-disable-next-line no-unused-vars
      const showData = this.allData.slice(start, end)
      // y轴
      // eslint-disable-next-line no-undef
      const sellerNames = showData.map((item) => {
        return item.name
      })
      // x轴
      // eslint-disable-next-line no-undef
      const sellerValue = showData.map((item) => {
        return item.value
      })
      const dataOption = {
        yAxis: {
          data: sellerNames
        },
        series: [
          {
            data: sellerValue
          }
        ]
      }
      this.chartInstance.setOption(dataOption)
      // 对图表对象进行鼠标事件的监听
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    startInterval () {
      if (this.timerId) {
        clearInterval(this.timerId)
      }
      this.timerId = setInterval(() => {
        this.currentPage++
        if (this.currentPage > this.totalPage) {
          this.currentPage = 1
        }
        this.updatechart()
      }, 3000)
    },
    // 当浏览器的大小发生变化的时候, 会调用的方法, 来完成屏幕的适配
    screenAdapter () {
      // console.log(this.$refs.seller_ref.offsetWidth)
      const titleFontSize = this.$refs.seller_ref.offsetWidth / 100 * 3.6
      // 和分辨率大小相关的配置项
      const adapterOption = {
        title: {
          textStyle: {
            fontSize: titleFontSize
          }
        },
        tooltip: {
          axisPointer: {
            lineStyle: {
              width: titleFontSize
            }
          }
        },
        series: [
          {
            barWidth: titleFontSize,
            itemStyle: {
              barBorderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0]
            }
          }
        ]
      }
      this.chartInstance.setOption(adapterOption)
      // 手动的调用图表对象的resize 才能产生效果
      this.chartInstance.resize()
    }
  }
}
</script>

  <style lang=less scoped>
  </style>

总结:

本次文章讲解项目创建以及1/6商家销售统计(横向柱状图)组件开发,请关注后续指标开发,最终整合大屏可视化

相关推荐
小马哥编程40 分钟前
Function.prototype和Object.prototype 的区别
javascript
小白学前端66641 分钟前
React Router 深入指南:从入门到进阶
前端·react.js·react
苹果醋341 分钟前
React系列(八)——React进阶知识点拓展
运维·vue.js·spring boot·nginx·课程设计
web130933203981 小时前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端
王小王和他的小伙伴1 小时前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
学前端的小朱1 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
outstanding木槿1 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
好名字08212 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
摇光932 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
隐形喷火龙2 小时前
element ui--下拉根据拼音首字母过滤
前端·vue.js·ui