故事發生在幾天前javascript
公司要求作個儀表盤,大體UI是這樣的
這不是爲難我胖虎嘛,因而找遍整個全網也沒找到類似的,只能本身手寫一個。html
然而,最開始是準備用極座標寫的java
折騰了一上午發現極座標作出的效果兩頭是360度的圓環,這使UI給的標註沒法實現,因而我又開始研究儀表盤,官方給的實例卻是挺炫酷git
當我感受快找到但願時,卻沒法實現兩端圓角編程
以及將刻度顯示在數字外,在網上找資料發現也有同窗遇到相同的問題,可是沒找到解決方法echarts
然而急中生智卻被我想到了一個方法,將這兩者合併一下dom
先簡單畫個儀表盤設計
設置一下他的屬性,去掉指針,去掉錶盤顏色,獲得只有刻度和數字的錶盤指針
以後將除了圓環之外的全部屬性配置一下實現這樣的效果code
忽然有內味了,這時咱們加上極座標環狀圖
然而兩者最大角度不一樣,咱們須要作一個換算,設計圖中儀表盤的角度至關於極座標的-30度到210度,兩者偏移值是240度除360度
也就是極座標得乘以2分之3(240分之360)纔是真實儀表盤的值
通過換算後,實現如下效果
源碼:https://gitee.com/DieHunter/myCode/tree/master/Echart/PolarGauge
一樣須要引入Echarts
HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .PolarGauge { margin: 100px auto; background: #000; width: 400px; height: 400px; } </style> <script src="./echarts.js"></script> <script src="./chart.js"></script> </head> <body> <div id="PolarGauge" class="PolarGauge"></div> </body> </html>
chart.js
var chart, option, data, timeTickId, timer, max; window.onload = function init() { chart = echarts.init(PolarGauge); //初始化chart容器 data = { //顯示的數據 "name": '館藏量', "num": 1000 } timer = 1.5 //刷新頻率 max = 1000 //最大館藏量 createPolarGauge() //配置chart } function createPolarGauge() { option = { angleAxis: { show: false, max: max * 3 / 2, //這裏將極座標最大值轉換成儀表盤的最大值,(360度除以240度) type: 'value', startAngle: 210, //極座標初始角度,從第一象限算起,大約在7-8點鐘角度之間 splitLine: { show: false //隱藏座標 } }, barMaxWidth: 18, //圓環寬度 radiusAxis: { //隱藏座標 show: false, type: 'category', }, polar: { //設置圓環位置和大小 center: ['50%', '50%'], radius: '296' }, series: [{ type: 'bar', data: [{ //上層圓環,用於顯示真實數據 value: data.num, itemStyle: { color: { //圖形漸變顏色方法,四個數字分別表明,右,下,左,上,offset表示0%到100% type: 'linear', x: 0, y: 0, x2: 1, //從左到右 0-1 y2: 0, colorStops: [{ offset: 0, color: '#CD48AE' // 0% 處的顏色 }, { offset: 1, color: '#2CABFC' // 100% 處的顏色 }], globalCoord: false // 缺省爲 false }, shadowColor: 'rgba(255, 255, 255, 0.2)', //加白色陰影產生高亮效果 shadowBlur: 10 } }], barGap: '-100%', //柱間距離,用來將上下兩層圓環重合 coordinateSystem: 'polar', //類型,極座標 roundCap: true, //頂端圓角 z: 2 //圓環層級,和zindex類似 }, { //下層圓環,用於顯示最大值 type: 'bar', data: [{ value: max, itemStyle: { color: '#265195', shadowColor: 'rgba(0, 0, 0, 0.2)', //加白色陰影產生高亮效果 shadowBlur: 5, shadowOffsetY: 2 } }], barGap: '-100%', //柱間距離,用來將上下兩層圓環重合 coordinateSystem: 'polar', //類型,極座標 roundCap: true, //頂端圓角 z: 1 //圓環層級,和zindex類似 }, { //儀表盤 type: 'gauge', radius: '95%', startAngle: 210, //起始角度,同極座標 endAngle: -30, //終止角度,同極座標 max: max, splitNumber: 5, //分割線個數(除原點外) axisLine: { // 座標軸線 show: false }, pointer: { show: false }, axisLabel: { // 座標軸數字 textStyle: { fontSize: 8, color: "#13B5FC" }, }, axisTick: { // 座標軸標記 length: 10, lineStyle: { color: "#13B5FC" } }, splitLine: { // 分隔線 length: 5, lineStyle: { width: 1, } }, title: { //標題,顯示'館藏量' textStyle: { color: '#fff', shadowColor: '#fff', fontSize: 30 }, offsetCenter: ["0", '-35%'] //位置偏移 }, detail: { //儀表盤數值 formatter: function (params) { var name = data.num.toString() var list = '' for (var i = 0; i < name.length; i++) { list += '{value|' + name[i] + '}' //每一個數字用border隔開 if (i !== name.length - 1) { list += '{margin|}' //添加margin值 } } return [list] }, offsetCenter: ["0", '5%'], rich: { //編輯富文本樣式 value: { width: 34, height: 42, borderColor: '#02A0F0', borderWidth: 2, borderRadius: 5, lineHeight: 1000, fontSize: 36, padding: [0, 0, 4, 0], color: '#fff', shadowColor: 'rgb(2,157,239)', shadowBlur: 5 }, margin: { width: 8, height: 42, } } }, data: [{ value: data.num, name: data.name }] } ] } timeTick() } function setOption() { //更新數據 data.num = parseInt(Math.random() * max) option.series[2].data[0].value = data.num option.series[0].data[0].value = data.num chart.setOption(option) } function timeTick() { //定時器,最好用延時加遞歸,若是用setInterval,容易形成堵塞 if (timeTickId) { clearTimeout(timeTickId) timeTickId = 0 } setOption() timeTickId = setTimeout(timeTick, 1000 * timer || 5000) }
總結:編程即生活,有時候不能死磕到底,換個角度也許會更好