vue中簡單封裝antV G2圖表

之前記過vue中antV G2圖表的使用http://www.itdecent.cn/p/a836ae8aeeb7(折線)

現(xiàn)在為了減少代碼量,簡單封裝一下,效果如下

image-20200909132848799.png

基本使用

子組件

新建LineChart.vue文件,里面是要封裝的內(nèi)容。

<!-- LineChart.vue 多折線-->
    
<template>
    <div>
        <div style="padding: 30px;height: 40vh;" :id="id"></div>    //id設(shè)成屬性值方便多次使用,樣式
    </div>
</template>



<script>
import { Chart } from "@antv/g2";   // 引入G2 Chart對象

export default {
    name: 'LineChart',              // 組件名
    props: {                        // 用到的屬性,在父組件里用v-modal綁定
        chartData: {                // 圖表要使用的數(shù)據(jù),在父組件里處理過、符合格式的數(shù)組
            type: Array,
            default: () => [],
        },
        id: {                       // 圖表容器id
            type: String,
            default: '',
        }
    },
    watch: {                        // watch 監(jiān)聽chartData,發(fā)生變化的時候更新圖表,初始化和更新數(shù)據(jù)的時候都適用
        chartData() {                        
            console.log('watch!!!!');
            this.initLineChart();
        }
    },
    data() {
        return {
            chart: null,            // 為了保證更新圖表的時候不會重復(fù)創(chuàng)建Chart對象,先聲明一下,方便之后判斷
        };
    },
    mounted() {
        // this.initLineChart();    // mounted中調(diào)用方法不適合異步請求數(shù)據(jù),initLineChart的時候,this.chartData是空的
    },
    methods: {
        initLineChart() {
            this.chart && this.chart.destroy();     // 上面說過的,如果圖表對象存在就先刪除,不然會重復(fù)創(chuàng)建,會顯示兩個圖表
            console.log('initLineChart success!!');
            
            this.chart = new Chart({
                container: this.id,                 // 用id屬性
                autoFit: true,
                // height: 500
            });

            this.chart.data(this.chartData);        // 圖表數(shù)據(jù)
            this.chart.scale({
                time: {
                    range: [0, 1]
                },
                count: {
                    min: 0,
                    nice: true
                },
            });
            this.chart.tooltip({
                showCrosshairs: true, // 展示 Tooltip 輔助線
                shared: true,
            });
            this.chart.axis('count', {
                 label: {
                     formatter: function formatter(val) {
                         return val ;
                     }
                 }
            });           
            this.chart.line().position('time*count').color('type').shape('smooth');
            this.chart.point().position('time*count').color('type').size(4).shape('circle').style({
                stroke: '#fff',
                lineWidth: 1
            });
            this.chart.render();
        },
    }
}
</script>

<style lang="less" scoped></style>

父組件引用子組件

<template>
    <div>
        <LineChart :chartData="chartdata" :id="'chartDiv'" />   //這里:id綁定格式要綁字符串
    </div>
</template>

<script>
import LineChart from '@/components'                            // 引入自定義的組件名,路徑按自己的情況
// import { LineChart } from '@/components'                     // components的index.js統(tǒng)一export之后的引用方法
const DataSet = require('@antv/data-set');                      // abtv處理數(shù)據(jù)的

export default {
  components: {
    LineChart,              // 引用后需要注冊組件
  },
  data() {
    return {
      chartdata:[],
      originData: [         // 實際從接口獲取,暫先用假的
          { time: "周一", 激活設(shè)備數(shù): 1234, 在線用戶數(shù): 124, 生理指標(biāo)數(shù):2352, 消息數(shù):283 },
          { time: "周二", 激活設(shè)備數(shù): 1245, 在線用戶數(shù): 364, 生理指標(biāo)數(shù):1534, 消息數(shù):234 },
          { time: "周三", 激活設(shè)備數(shù): 1456, 在線用戶數(shù): 428, 生理指標(biāo)數(shù):1926, 消息數(shù):992 },
          { time: "周四", 激活設(shè)備數(shù): 1526, 在線用戶數(shù): 523, 生理指標(biāo)數(shù):2538, 消息數(shù):720 },
          { time: "周五", 激活設(shè)備數(shù): 1548, 在線用戶數(shù): 92, 生理指標(biāo)數(shù):945, 消息數(shù):1347 },
          { time: "周六", 激活設(shè)備數(shù): 1798, 在線用戶數(shù): 242, 生理指標(biāo)數(shù):2523, 消息數(shù):124 },
          { time: "周日", 激活設(shè)備數(shù): 1723, 在線用戶數(shù): 131, 生理指標(biāo)數(shù):1583, 消息數(shù):732 },
      ]
    };
  },
  mounted() {
    this.initData();                // 調(diào)用獲取數(shù)據(jù)的方法
      // console.log('chartdata =>',this.chartdata)
      // console.log('ref.chartData =>',this.$refs.chart.chartData)
  },
  methods: {
    initData() {                    // 得到數(shù)據(jù),對數(shù)據(jù)格式進行一些處理,上篇說過。
      let ds = new DataSet();       // 上篇是雙曲線,一條轉(zhuǎn)成兩條,現(xiàn)在就是一條轉(zhuǎn)換成四條,方法都一樣。
      let dv = ds.createView().source(this.originData);
      // fold 方式完成了行列轉(zhuǎn)換,如果不想使用 DataSet 直接手工轉(zhuǎn)換數(shù)據(jù)即可
      dv.transform({
          type: 'fold',
          fields: ['激活設(shè)備數(shù)','在線用戶數(shù)','生理指標(biāo)數(shù)','消息數(shù)'],  // 展開字段集
          key: 'type',                                          // key字段
          value: 'count'                                        // value字段 這個字段和time字段和子組件里的字段是要對應(yīng)的。
      });
      this.chartdata = dv.rows;     // 處理過后的數(shù)據(jù)賦值給this.chartdata
      console.log('initData!!!')
    },
  },
}
</script>

<style lang="less" scoped>
</style>

★需求是Tabs頁展示不同時段的數(shù)據(jù)統(tǒng)計結(jié)果

(明明用按鈕更方便?,用按鈕的話只要一個圖表,更新數(shù)據(jù)就可以了。更新數(shù)據(jù)相關(guān)https://blog.csdn.net/weixin_42275932/article/details/90080199?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight

UI組件用的是antdv,將四個圖表掛在四個tab-pane上,需要注意的是所有tab-pane頁都要強行渲染,api用forceRender(被隱藏時是否渲染)

<div class="dataStastic">
    <a-tabs 
        defaultActiveKey="1"
        size="large"
        :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}"
    >
        <a-tab-pane key="1" tab="小時">
            <LineChart :chartData="chartdataHour" :id="'chartDiv1'" />
        </a-tab-pane>
        <a-tab-pane key="2" tab="天" forceRender>
            <LineChart :chartData="chartdataDay" :id="'chartDiv2'" />
        </a-tab-pane>
        <a-tab-pane key="3" tab="周" forceRender>
            <LineChart :chartData="chartdataWeek" :id="'chartDiv3'" />
        </a-tab-pane>
        <a-tab-pane key="4" tab="月" forceRender>
            <LineChart :chartData="chartdataMonth" :id="'chartDiv4'" />
        </a-tab-pane>
    </a-tabs>
</div>

不渲染的話是空白的?。?!不渲染的話是空白的?。。〔讳秩镜脑捠强瞻椎模。。?/strong>


優(yōu)化

目前是橫坐標(biāo)的字段是time,縱坐標(biāo)的字段是count,默認(rèn)有坐標(biāo)軸,輔助線,和圖例。

控制一下坐標(biāo)軸輔助線和圖例的顯示,將高度也放在父組件里傳入。

LineChart.vue的prop:

props: {
        chartData: {
            type: Array,
            default: () => [],
        },
        id: {
            type: String,
            default: '',
        },
        height: {           //高度
            type: Number,
            default: 300,
        },
        legend: {           //圖例
            type: Boolean,
            default:true,
        },
        axisX: {            //橫坐標(biāo)
            type: Boolean,
            default:true,
        },
        axisY: {            //縱坐標(biāo)
            type: Boolean,
            default:true,
        },
    },

LineChart.vue的initLineChart:

initLineChart() {
    this.chart && this.chart.destroy();     //如果存在就先刪除
    console.log('initLineChart success!!');
    console.log(this.chartData)
    this.chart = new Chart({
        container: this.id,
        autoFit: true,
        height: this.height,                // 控制高度
    });

    this.chart.data(this.chartData);
    this.chart.scale({
        time: {
            range: [0, 1]
        },
        count: {
            min: 0,
            nice: true
        },
    });
    this.chart.tooltip({
        showCrosshairs: true, // 展示 Tooltip 輔助線
        shared: true,
    });
    this.chart.axis('count',this.axisY);    //控制橫縱坐標(biāo),圖例
    this.chart.axis('time',this.axisX);
    this.chart.legend(this.legend);
    
    this.chart.line().position('time*count').color('type').shape('smooth');
    this.chart.point().position('time*count').color('type').size(4).shape('circle').style({
        stroke: '#fff',
        lineWidth: 1
    });
    this.chart.render();
},

父組件的template:

<LineChart :chartData="chartdata" :id="'chartDiv'" :height="100" :legend="false" :axisX="false" :axisY="false"/>

這樣就是高度100,不顯示圖例,也不顯示橫坐標(biāo)、縱坐標(biāo)。

其他想要控制的也可以這樣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容