之前記過vue中antV G2圖表的使用http://www.itdecent.cn/p/a836ae8aeeb7(折線)
現(xiàn)在為了減少代碼量,簡單封裝一下,效果如下

基本使用
子組件
新建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)。
其他想要控制的也可以這樣。