目錄
一.兩種引入方式
1.浏覽器引入
2.通過 npm 安裝
二. 兩種使用方式
1. 在配置了webpack或使用vue-cli建構的vue項目使用
2. 另一種使用方式是在html中直接使用
三. vue循環渲染圖表,動态綁定Id
最近在研究資料可視化,了解到會有移動端的資料可視化需求,是以看到了阿裡出的Antv F2.
官網有如下簡介: F2,一個專注于移動,開箱即用的可視化解決方案,完美支援 H5 環境同時相容多種環境(node, 小程式,weex)。完備的圖形文法理論,滿足你的各種可視化需求。專業的移動設計指引為你帶來最佳的移動端圖表體驗。 那我們在vue項目中應當如何使用呢?
一.兩種引入方式
1.浏覽器引入
既可以通過将腳本下載下傳到本地也可以直接引入線上資源。
引入線上資源
<script src="https://gw.alipayobjects.com/os/antv/assets/f2/3.4.2/f2.min.js"></script>
友情提醒:請按需更新版本号。
引入本地腳本
<script src="./f2.js"></script>
你也可以直接通過 unpkg 下載下傳。
2.通過 npm 安裝
npm install @antv/f2 --save
安裝完之後,在入口檔案main.js裡引入
import F2 from '@antv/f2'
Vue.prototype.$F2= F2;
二. 兩種使用方式
1. 在配置了webpack或使用vue-cli建構的vue項目使用
在chart.vue元件中使用F2建構圖表:
<template >
<div class="about">
<canvas id="myChart" width="400" height="260"></canvas>
</div>
</template>
export default {
name:'about',
data(){
return {
data:[
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 }
]
}
},
methods:{
drawChart(){
// Step 1: 建立 Chart 對象
const chart = new this.$F2.Chart({
id: 'myChart',
pixelRatio: window.devicePixelRatio // 指定分辨率
});
// Step 2: 載入資料源
console.log(this.data);
chart.source(this.data);
// Step 3:建立圖形文法,繪制柱狀圖,由 genre 和 sold 兩個屬性決定圖形位置,genre 映射至 x 軸,sold 映射至 y 軸
chart.interval().position('genre*sold').color('genre');
// Step 4: 渲染圖表
chart.render();
}
},
mounted(){
var v = this;
this.$nextTick(()=>{
v.drawChart();
});
},
created(){
}
}
為什麼我們要将調用畫圖的函數放置到vue.$nextTick函數裡面呢? 因為我們要保證dom渲染完成之後去擷取dom元素,再進行畫圖。如果這裡我們不放置到這個函數裡面,會報找不到ID的錯誤。
生成的圖表如圖:

2. 另一種使用方式是在html中直接使用
html引入部分的代碼
<link rel="stylesheet" href="https://gw.alipayobjects.com/os/rmsportal/YmDAMEQVbLJpVbKiRQVX.css" target="_blank" rel="external nofollow" />
<script src="https://gw.alipayobjects.com/os/antv/assets/f2/3.4.2/f2.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://gw.alipayobjects.com/os/rmsportal/NjNldKHIVQRozfbAOJUW.js"></script>
script代碼
window.onload = function(){
var vm = new Vue({
el: '#app',
data(){
return {
data:[],
}
},
methods:{
getData(){
let list = [{"tem":"10","time":"2016-08-08 00:00:00"},{"tem":"22","time":"2016-08-08 00:10:00"},{"tem":"20","time":"2016-08-08 00:30:00"},{"tem":"26","time":"2016-08-09 00:35:00"},{"tem":"20","time":"2016-08-09 01:00:00"},{"tem":"26","time":"2016-08-09 01:20:00"},{"tem":"28","time":"2016-08-10 01:40:00"},{"tem":"20","time":"2016-08-10 02:00:00"}];
var chart = new F2.Chart({
id: 'mountNode',
pixelRatio: window.devicePixelRatio,
padding: [ 30, 24, 30, 40],
});
var defs = {
time: {
type: 'timeCat',
mask: 'MM-DD',
tickCount: 3,
range: [0, 1]
},
tem: {
tickCount: 5,
min: 0,
alias: '算力'
}
};
if(list.length>0){
chart.source(list, defs);
chart.axis('time', {
label: function label(text, index, total) {
var textCfg = {};
if (index === 0) {
textCfg.textAlign = 'left';
} else if (index === total - 1) {
textCfg.textAlign = 'right';
}
return textCfg;
}
});
chart.axis('time',{
label: {
fill: '#52FFFF'
}
});
chart.axis('tem',{
label: {
fill: '#52FFFF'
}
});
chart.tooltip({
showCrosshairs: true,
});
chart.guide().text({
position: [ 'min', 'max' ], // x 軸最小值, y 軸最大值
content: '算力',
style: {
textAlign: 'start',
textBaseline: 'top',
fill:'#52FFFF'
},
offsetY: -10,
offsetX: -10, // 可以通過 padding 值配合來保證顯示位置
});
chart.line().position('time*tem').shape('smooth');
chart.point().position('time*tem').shape('smooth').style({
stroke: '#fff',
lineWidth: 1
});
chart.render();
// document.getElementById("secondid").value = list;
}
},
},
mounted(){
this.getData();
}
})
}
效果圖:
三. vue循環渲染圖表,動态綁定Id
需求是後端傳回一個圖表數組, 前端需要展示這個數組,難點就是每個圖表都需要繪制一個canvas, 并且每個id需要唯一, 是以就可以借助數組下标的索引值為id名稱,具體如下:
html代碼
<template>
<div class='chart-container'>
<div class="chart-wraper" v-for='item,index in chartList'>
<canvas :id='`mountNode_${index}`' class='chart-inner'></canvas>
</div>
</div>
</template>
js代碼
import BlockService from '@/services/BlockService'
export default {
data(){
return {
chartList:[], //圖表資料
}
},
methods:{
getData(datas){
let defs = {
day: {
type: 'timeCat',
mask: 'MM-DD',
tickCount: 3,
range: [0, 1]
},
values: {
tickCount: 5,
min: 0,
alias: name
}
};
let chart = {};
this.$nextTick(() =>{
for(let i=0;i<datas.length;i++){
chart[i] = new this.$F2.Chart({
id: 'mountNode_'+i,
pixelRatio: window.devicePixelRatio,
padding: [ 30, 24, 30, 40],
});
if(datas[i].values.length>0){
chart[i].source(datas[i].values, defs);
chart[i].axis('day', {
label: function label(text, index, total) {
var textCfg = {};
if (0 === 0) {
textCfg.textAlign = 'left';
} else if (0 === total - 1) {
textCfg.textAlign = 'right';
}
return textCfg;
}
});
chart[i].axis('day',{
label: {
fill: '#52FFFF'
}
});
chart[i].axis('values',{
label: {
fill: '#52FFFF'
}
});
chart[i].tooltip({
showCrosshairs: true,
});
chart[i].guide().text({
position: [ 'min', 'max' ], // x 軸最小值, y 軸最大值
content: datas[i].name,
style: {
textAlign: 'start',
textBaseline: 'top',
fill:'#52FFFF'
},
offsetY: -20,
offsetX: -20, // 可以通過 padding 值配合來保證顯示位置
});
chart[i].line().position('day*values').shape('smooth');
chart[i].point().position('day*values').shape('smooth').style({
stroke: '#fff',
lineWidth: 1
});
chart[i].render();
}
}
});
},
},
created(){
BlockService.getChartList(this, data=>{
this.chartList = data;
this.getData(data);
})
}
}
上面代碼中, datas是從接口擷取的圖表數組, 含有多個圖表的資料,後端傳回的資料接口如下:
{
"code":0,
"message":"success",
"data":[
{
"values":[
{
"values":0,
"day":"2019-10-18"
}
],
"name":"算力",
"templateId":"02d9f54bd0154832b5cdddde5c479756"
},
{
"values":[
{
"values":99964647,
"day":"2019-10-18"
}
],
"name":"算率",
"templateId":"202b9359c43d4096ad94d3eba0388612"
}
]
}
效果圖:
說明: 1. id要保證唯一, 需要使用數組下标作為辨別,
2. 使用f2有個不太靈活的地方, 後端傳回的資料字段名稱要跟繪制圖表的橫縱坐标對應, 上面代碼,day對應橫坐标的日期, values對應縱坐标的數值.
3. 在繪制圖表的函數中,一定要放在vue的$nextTick方法裡, 否則會找不到對應id, 圖表無法渲染, 這點很重要.
更新
需求1: toolTip提示框顯示縱坐标名稱
實作:
chart[i].tooltip({
showCrosshairs: true, //是否顯示輔助線
crosshairsStyle: {
stroke: 'rgba(255,255,255,.25)',
lineWidth: 2
}, // 配置輔助線的樣式
snap: true,
showTitle:true,
offsetY: 20, // y 方向的偏移
onShow: function onShow(ev) {
var items = ev.items;
items[0].name = datas[i].name; //name為需要顯示的縱坐标的名稱
},
});
需求2:縱坐标需要顯示百分比%
實作:
把上面的onShow函數加上以下代碼
onShow: function onShow(ev) {
var items = ev.items;
items[0].name = datas[i].name;
if(datas[i].name == '算率'){
items[0].value = (items[0].value*100).toFixed(2) + '%';
}else{
items[0].value = items[0].value
}
},