Vue+Echarts(圖表可視化)


Vue+Echarts

1 . 前端項目的准備

2 . 項目的基本配置

3 . media 組件實例

4 . 詳細文檔

相關網址

vue網址:https://cn.vuejs.org/v2/guide/

echarts: https://echarts.apache.org/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts

 

1 .前端項目的准備

1.1vue-cli 腳手架安裝

在全局環境中安裝 vue-cli 腳手架 
npm install -g @vue/cli

1.2  使用vue創建一個項目

vue create yuqing_front(項目名)

配置:

 

1.3 運行項目

cd yuqing_front
npm run serve
1.4刪除無關代碼
- 修改 App.vue 中的代碼,將布局和樣式刪除, 變成如下代碼
<template> 
    <div id="app">
     <router-view/>
     </div> 
</template> 

<style lang="less">
 </style>    
- 刪除 components/HelloWorld.vue 這個文件
- 刪除 views/About.vue 和 views/Home.vue 這兩個文件
- 修改 router/index.js 中的代碼,去除路由配置和 Home 組件導入的代碼
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = []
const router = new VueRouter({
  routes
})
export default router

 

2 項目的基本配置

-  2.1vue.config.js

// 使用vue-cli創建出來的vue工程, Webpack的配置是被隱藏起來了的
// 如果想覆蓋Webpack中的默認配置,需要在項目的根路徑下增加vue.config.js文件
 
module.exports={
    devServer:{
        port :8999, // 端口號的配置
        open:true // 自動打開瀏覽器
    }
}
 
-  2.2 將資料文件夾中的 static 目錄復制到 public 目錄之下 (相關echart文件)
        點擊獲取static
 
<!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 src="static/lib/echarts.min.js"></script>
    <script src="static/theme/chalk.js"></script>
    <script src="static/theme/vintage.js"></script>
  </body>
</html>
public/index.html(引入echarts包)
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 引入字體的文件
import './assets/font/iconfont.css'
// 引入全局的樣式文件
import './assets/css/global.less'
import axios from 'axios'
// 請求基准路徑的配置
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/'
// 將axios掛載到Vue的原型對象上
// 在別的組件中 this.$http
Vue.prototype.$http = axios

// 將全局的echarts對象掛載到Vue的原型對象上
// 別的組件中 this.$echarts
Vue.prototype.$echarts = window.echarts

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
main.js
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;
}
assets/css/global.less

-  2.3 單獨組件開發

  --組件結構設計 

  --圖表 Media.vue 基本功能的實現 

  --(分頁動畫的實現)

  --UI 效果調整 

  --分辨率適配

 

-   3 media組件

import Vue from 'vue'
import VueRouter from 'vue-router'


Vue.use(VueRouter)

const routes = [
  {
    path: '/media',
    name: 'media',
    component: () => import('@/views/MediaPage'),
  },
]

const router = new VueRouter({
  routes
})

export default router
router/index.js
<template>
  <div class="com-page">
      <media></media>
  </div>
</template>

<script>
import Media from '@/components/Media.vue'
export default {
  components: { Media },

}
</script>

<style>

</style>
MediaPage.vue(測試)
<!-- 商家銷量統計的橫向柱狀圖 -->
<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, // 一共有多少頁
      timerId: null // 定時器的標識
    }
  },
  mounted () {
    this.initChart()
    this.getData()
    window.addEventListener('resize', this.screenAdapter)
    // 在頁面加載完成的時候, 主動進行屏幕的適配
    this.screenAdapter()
  },
  destroyed () {
    clearInterval(this.timerId)
    // 在組件銷毀的時候, 需要將監聽器取消掉
    window.removeEventListener('resize', this.screenAdapter)
  },
  methods: {
    // 初始化echartInstance對象
    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)
      // 對圖表對象進行鼠標事件的監聽
      this.chartInstance.on('mouseover', () => {
        clearInterval(this.timerId)
      })
      this.chartInstance.on('mouseout', () => {
        this.startInterval()
      })
    },
    // 獲取服務器的數據
    async getData () {
      // http://127.0.0.1:8888/api/seller
      const { data: ret } = await this.$http.get('seller')
      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
      this.updateChart()
      // 啟動定時器
      this.startInterval()
    },
    // 更新圖表
    updateChart () {
      const start = (this.currentPage - 1) * 5
      const end = this.currentPage * 5
      const showData = this.allData.slice(start, end)
      const sellerNames = showData.map((item) => {
        return item.name
      })
      const sellerValues = showData.map((item) => {
        return item.value
      })
      const dataOption = {
        yAxis: {
          data: sellerNames
        },
        series: [
          {
            data: sellerValues
          }
        ]
      }
      this.chartInstance.setOption(dataOption)
    },
    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>
Media.vue

   示例代碼 demo

 

-  4 詳細文檔

   文檔詳情點擊查看

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM