大屏成像原理幾乎都是投屏,也就是把電腦屏幕經過有線信號投放到大屏上,電腦上呈現什麼內容,大屏上就會呈現什麼內容,因此電腦屏幕橫向和縱向上都不能出現滾條。在網上看了一些適配方案,最後參考了大屏數據可視化——屏幕適配方案(多分辨率下),用CSS3的scale,將容器設置爲設計稿寬高,如3840*2160,動態根據瀏覽器視口的寬高進行縮放,從而實現容器始終鋪滿瀏覽器視口,而不出現滾動條。css
容器組件的結構:html
<template>
<div class="bsd-frame" :style="{'background': bgColor}" ref="bsdFrame">
<slot></slot>
</div>
</template>
複製代碼
第一步、獲取容器實際寬高,一般是設計稿寬高,或者電腦屏幕的寬高。前端
setSize () {
this.frameWidth = this.width || screen.width
this.frameHeight = this.height || screen.height
const frame = this.$refs.bsdFrame //爲容器根元素設置寬高
frame.style.width = this.frameWidth + 'px'
frame.style.height = this.frameHeight + 'px'
}
複製代碼
第二步、根據瀏覽器視口的的寬高,爲容器設置縮放比例。vue
setScale () {
const bodyWidth = document.body.clientWidth //前提是html,body的height: 100%; width: 100%
const bodyHeight = document.body.clientHeight
const scaleX = bodyWidth / this.frameWidth
const scaleY = bodyHeight / this.frameHeight
this.$refs.bsdFrame.style.transform = `scale(${scaleX},${scaleY})`
}
複製代碼
第三部、監聽resize事件,每次觸發resize事件時,從新計算容器縮放比例。vuex
mounted () {
this.setSize()
this.setScale()
window.addEventListener('resize', this.setScale)
},
destroyed () {
window.removeEventListener('resize', this.setScale)
}
複製代碼
主要用了柱狀圖、折線圖、餅圖等基礎圖表,以及地圖。這部分主要的工做就是對着echarts配置項調整圖標配置。 echarts.apache.org/zh/option.h…apache
echarts5對按需引入做了調整。將渲染器、組件和圖表從echarts核心分離開來,根據須要進行引用,以前默認包含canvas和svg渲染器,如今能夠根據須要選擇canvas渲染器或是svg渲染器。組件和圖表的按需引入方式和以前也不同。好比要畫一個帶標題的折線圖,就像下面這樣引入TitleComponent、LineChart。canvas
import * as echarts from 'echarts/core';
import { TitleComponent } from 'echarts/components';
import { LineChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use(
[TitleComponent, LineChart, CanvasRenderer]
);
複製代碼
使用:api
var dom = document.getElementById('main');
var myChart = echarts.init(dom); //初始化
var option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}]
};
option && myChart.setOption(option); // 設置選項
複製代碼
要在一個dom中繪製圖表,首先是echarts.init(dom)
初始化一個echarts實例,而後爲這個實例設置選項myChart.setOption(option)
,就能夠完成圖表的繪製了。能夠參考官網的案例,echarts案例 。數組
當數據發生改變,要從新繪製,就再次調用myChart.setOption(newOption)
。瀏覽器
項目中不少地方都要用到echarts,以前用的vue-echarts組件庫
是基於echarts4的,因此就簡易地基於echarts5封裝了一個組件,能夠根據傳入的option初始化圖表,當option發生改變,從新渲染圖表。
<template>
<div class="echarts"></div>
</template>
<script>
import * as echarts from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([CanvasRenderer])
export default {
name: 'vue-echarts',
props: {
options: {
type: Object,
required: true
}
},
watch: {
options (newValue, oldValue) {
if (this.chart && newValue) { //沒有設置deep:true,因此當數據改變時,要改變option指針,才能觸發該方法。
this.chart.setOption(newValue)
}
}
},
methods: {
init (opt) {
if (!this.chart) {
this.chart = echarts.init(this.$el)
}
this.chart.setOption(this.options)
}
},
mounted () {
this.init()
}
}
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
}
</style>
複製代碼
使用:
<vue-echarts :options="chartOption" />
computed: {
chartOption () {
const categorySales = this.$store.state.categorySales
categoryOpt.series[0].data = categorySales
return Object.assign({}, categoryOpt)
}
}
複製代碼
滾動播放用的是transition,改變最上面一行的高度height,
transition: height 0.3s linear;
當最上面一行隱藏後,將它的數據從數組頭部移到尾部。實現循環滾動。
//this.rowHeight爲計算出的每一行的高度,這裏是將全部行高都還原成初始值,len是數組長度
this.rowHeights = new Array(len).fill(this.rowHeight)
//將最上面一行的高度設爲0
this.rowHeights.splice(0, 1, 0)
//將數組頭部的數據移到尾部, this.currentIndex爲移動指針,初始值爲0
const temp = this.rowsx.slice(this.currentIndex)
temp.push(...this.rowsx.slice(0, this.currentIndex))
this.rowsData = temp
this.currentIndex += 1
複製代碼
<div v-for="(item, index) in rowsData" :key = "item.index"></div>
複製代碼
echarts.registerMapapi支持自定義地理座標系,如echarts.registerMap('china', map)
,第一個參數是自定義的地圖名稱,第二參數是GeoJson格式的數據,長下面這樣: GeoJson格式的數據能夠在這個網站輸入地名獲取。 datav.aliyun.com/tools/atlas…
自定義地理座標系的使用:
type: 'map'
的圖表類型series: [
{
name: '產品流向分佈',
type: 'map',
map: 'china',
zoom: 1.6,
center: [104.114129, 36.050339],
itemStyle: {
borderColor: 'blue',
borderWidth: 2
}
}
]
複製代碼
再加上視覺映射組件
visualMap
, 就能夠實現熱力分佈地圖。
visualMap: {
show: false,
min: 0,
max: 10000,
seriesIndex: [0],
inRange: {
color: ['#a7d5f2', '#3f95ff', '#5470c6']
}
},
series: [
{
name: '產品流向分佈',
type: 'map',
map: 'china',
zoom: 1.6,
center: [104.114129, 36.050339],
itemStyle: {
borderColor: 'blue',
borderWidth: 2
}
}
]
複製代碼
geo: {
map: 'china', //自定義的地圖名稱
zoom: 1.6,
center: [104.114129, 36.050339],
itemStyle: {
borderColor: 'blue',
borderWidth: 2
}
},
series: [
{
type: 'effectScatter',
coordinateSystem: 'geo', //指定geo座標系
symbolSize: function (val) {
return val[2] / 200
},
rippleEffect: {
brushType: 'stroke'
},
label: {
show: true,
position: ['20', '0'],
formatter: '{b}',
fontSize: 16
},
itemStyle: {
color: 'yellow'
}
}]
複製代碼
自定義地理座標系的使用是很常見的,省市區域的一些統計狀況均可以用上述的方法進行實現。
項目用的是模擬數據,用vuex進行數據的管理通訊。更新方式採用定時輪詢。
//Home.vue
created () {
this.$store.dispatch('updateAll')
setInterval(() => { // 模擬定時輪詢
this.$store.dispatch('updateAll')
}, 5 * 60 * 1000)
}
複製代碼
在actions中模擬請求數據。
actions: {
updateAll (context) {
setTimeout(() => { // 模擬成功請求接口數據
// 接口返回,數據變化,更新狀態
//context.commit('updateOverall', data)
...
}, 1000)
}
},
複製代碼
在組件的computed中處理使用數據:
computed: {
chartOption () {
const categorySales = this.$store.state.categorySales
categoryOpt.series[0].data = categorySales
return Object.assign({}, categoryOpt)
}
}
複製代碼
關注公衆號:Alasolala,回覆:數據大屏,獲取源碼。