日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

vue基于Echarts的拖拽數據可視化功能實現

瀏覽:23日期:2022-10-21 11:58:34
背景

我司產品提出了一個需求,做一個數據基于Echars的可拖拽縮放的數據可視化,上網百度了一番,結果出現了兩種結局,一種花錢買成熟產品(公司不出錢),一種沒有成熟代碼,只能自己寫了,故事即將開始,敬請期待......。 不,還是先上一張效果圖吧,請看......

vue基于Echarts的拖拽數據可視化功能實現

前期知識點1. offset(偏移量)

定義:當前元素在屏幕上占用的空間,如下圖:

其中:

offsetHeight: 該元素在垂直方向上的占用的空間,單位為px,不包括margin。

offsetWidth:該元素在水平方向上的占用空間,單位為px,不包括margin。

offsetLeft: 該元素距離左側并且是定位過(relative || absolute)的父元素內邊框的距離。注意:如果父元素中沒有一個是定位的,則是距離body元素的距離。

offsetTop:該元素距離頂部并且是定位過(relative || absolute)的父元素內邊框的距離。注意:如果父元素中沒有一個是定位的,則是距離body元素的距離。

2. 鼠標事件

2.1 當前鼠標的坐標點

clientX:返回鼠標觸點相對于瀏覽器可視區域的X坐標,單位為px,這個屬性值可以根據用戶對可視區的縮放行為發生變化。

clientY:返回鼠標觸點相對于瀏覽器可視區域的Y坐標,單位為px,這個屬性值可以根據用戶對可視區的縮放行為發生變化。

2.2 相關的鼠標事件

ondragstart: 規定當元素被拖動時,發生什么,該屬性調用一個函數,drag(event),它規定了被拖動的數據。可通過dataTransfer.setData() 方法設置被拖數據的數據類型和值:

function drag(ev){ ev.dataTransfer.setData('Text',ev.target.id);}

ondragover: 規定在何處放置被拖動的數據,默認地,無法將數據/元素放置到其他元素中。如果需要設置允許放置,我們必須阻止對元素的默認處理方式。這要通過調用 ondragover 事件的 event.preventDefault() 方法:

event.preventDefault()

ondrop:當放置被拖數據時,會發生 drop 事件。ondrop 屬性調用了一個函數,drop(event):

function drop(ev){ // 避免瀏覽器對數據的默認處理(drop 事件的默認行為是以鏈接形式打開) ev.preventDefault(); // 獲得被拖的數據。該方法將返回在 setData() 方法中設置為相同類型的任何數據。 var data=ev.dataTransfer.getData('Text'); // 把被拖元素追加到放置元素(目標元素)中 ev.target.appendChild(document.getElementById(data));}

onMouseDown: 鼠標上的按鈕被按下時觸發的事件

onMouseMove:鼠標移動時觸發的事件

onmouseup:鼠標按下后,松開時激發的事件

拖拽功能

本功能以Echarts圖表中柱狀圖為例,進行講解:

先定義可拖拽元素

<div> <el-button class='drag-button' type='success' draggable='true' @dragstart.native='dragStart($event,’histogram’)'> 柱狀圖 </el-button> </div>

注意:元素默認是不能進行拖拽的,需要將draggable屬性設置為'true',即draggable='true'

dragStart(event,type){ event.dataTransfer.setData('Text',type); },

定義放置區域

<div @drop.prevent='drop($event)' @dragover.prevent=''> <div id='’histogram’></div></div>

其中drop事件如下:

drop(event){ const data=event.dataTransfer.getData('Text'); if(data === ’histogram’){ var myChart = echarts.init(document.getElementById(’histogram’)); // 指定圖表的配置項和數據 var option = { title: { text: ’ECharts 入門示例’ }, tooltip: {}, legend: { data:[’銷量’] }, xAxis: { data: ['襯衫','羊毛衫','雪紡衫','褲子','高跟鞋','襪子'] }, yAxis: {}, series: [{ name: ’銷量’, type: ’bar’, data: [5, 20, 36, 10, 10, 20] }] }; // 使用剛指定的配置項和數據顯示圖表。 myChart.setOption(option); }}

基于自己封裝的組件的源碼請看github:github地址

效果圖如下:

vue基于Echarts的拖拽數據可視化功能實現

拖動功能

此功能用到了上面提到的offsetLeft、offsetTop、clientX,clientY。實現思路如下:

(1)當鼠標剛按下去時,記錄當前元素距離帶定位的父元素的offsetLeft、offsetTop距離;以及當前鼠標在瀏覽器可視區的坐標clientX、clientY的距離。

(2)分別計算兩者的差值作為偏移常量,如下:

let disX = e.clientX - el.offsetLeft;let disY = e.clientY - el.offsetTop;

(3)監聽鼠標的移動事件,獲取當前鼠標距離瀏覽器可是區域的坐標clientX,clientY;然后減去偏移常量,即為當前元素的坐標

let tX = e.clientX - disX; let tY = e.clientY - disY; el.style.left = tX + ’px’; el.style.top = tY + ’px’;

說明:el為當前圖表對象

由于本人封裝了通用vue組件,詳細拖拽方法代碼如下:

// 初始化可拖拽方法 initDrag(){ let el = this.$el; el.onmousedown = (e)=>{ e.preventDefault(); e.target.style.cursor = ’move’; //鼠標按下,計算鼠標觸點距離元素左側和頂部的距離 let disX = e.clientX - el.offsetLeft; let disY = e.clientY - el.offsetTop; // console.log(’22222’,document); document.onmousemove = function (e) { //計算需要移動的距離 let tX = e.clientX - disX; let tY = e.clientY - disY; //移動當前元素 if (tX >= 0 && tX <= window.innerWidth - el.offsetWidth) {el.style.left = tX + ’px’; } if (tY >= 0 && tY <= window.innerHeight - el.offsetHeight) {el.style.top = tY + ’px’; } }; //鼠標松開時,注銷鼠標事件,停止元素拖拽。 document.onmouseup = function (e) {document.onmousemove = null;document.onmouseup = null;e.target.style.cursor = ’default’; }; } },

如果想看封裝的組件,請查看github地址:github地址

拖動效果如下圖:

vue基于Echarts的拖拽數據可視化功能實現

縮放功能

此功能用到了上面提到的 offsetWidth、offsetHeight、offsetLeft、offsetTop、clientX,clientY。實現思路如下:

(1)先設置可縮放的四個拖拽方框

<div v-show='isResize && resizeFlag' ref='resizeDivTag' id='resizeDivTag'><span class='br'></span><span class='bl'></span><span class='tr'></span><span class='tl'></span> </div>

其中isResize 與 resizeFlag表示是否可縮放以及是否可拖拽

(2)為每個可可縮放方框設置縮放函數,請看注釋

// 初始化可縮放 initResize(){let el = this.$el; //獲取當前元素let spanNodes = this.$refs.resizeDivTag.childNodes;for(let i=0;i<spanNodes.length;i++){ this.resizeElementFun(spanNodes[i],el); // 分別為四個縮放方框設置監聽事件} }, resizeElementFun(element,el){element.onmousedown = function(ev){ console.log(’我是按下的元素’) let oEv = ev || event; oEv.stopPropagation(); let oldWidth = el.offsetWidth; // 當前元素的寬度 let oldHeight = el.offsetHeight; // 當前元素的高度 console.log(’-----’+ oldWidth+’----’+oldHeight); let oldX = oEv.clientX; // 當前鼠標對于瀏覽器可視區域的X坐標 let oldY = oEv.clientY; // 當前鼠標對于瀏覽器可視區域的Y坐標 let oldLeft = el.offsetLeft; // 當前元素對于父級定位元素的寬度 let oldTop = el.offsetTop; // 當前元素對于父級定位元素的高度 console.log(’--zuo---’+ oldLeft+’--gao--’+oldTop); document.onmousemove = function(ev){ // oEv.stopPropagation(); let oEv = ev || event; let disY = (oldTop + (oEv.clientY - oldY)); // 當前縮放的元素距離定位父元素的高度 // let disX = (oldLeft + (oEv.clientX - oldLeft)); let disX = (oldLeft + (oEv.clientX - oldX)); // 當前縮放的元素距離定位父元素的寬度 if(disX>oldLeft+oldWidth){disX=oldLeft+oldWidth } if(disY>oldTop+oldHeight){disY=oldTop+oldHeight } if(element.className == ’tl’){ // 左上縮放時 el.style.width = oldWidth - (oEv.clientX - oldX) + ’px’; // 元素寬度= 縮放前寬度-鼠標當前坐標與原始坐標差值 el.style.height = oldHeight - (oEv.clientY - oldY) + ’px’; // 元素寬度= 縮放前高度-鼠標當前坐標與原始坐標差值 el.style.left = disX + ’px’; // 元素距離父元素的距離 = el.style.top = disY + ’px’; } else if (element.className == ’bl’){ // 左下 el.style.width = oldWidth - (oEv.clientX - oldX) + ’px’; el.style.height = oldHeight + (oEv.clientY - oldY) + ’px’; el.style.left = disX + ’px’; // el.style.bottom = oldTop + (oEv.clientY + oldY) + ’px’; } else if (element.className == ’tr’){ //右上 el.style.width = oldWidth + (oEv.clientX - oldX) + ’px’; el.style.height = oldHeight - (oEv.clientY - oldY) + ’px’; el.style.right = oldLeft - (oEv.clientX - oldX) + ’px’; el.style.top = disY + ’px’; } else if (element.className == ’br’){ //右下 el.style.width = oldWidth + (oEv.clientX - oldX) + ’px’; el.style.height = oldHeight + (oEv.clientY - oldY) + ’px’; el.style.right = oldLeft - (oEv.clientX - oldX) + ’px’; // el.style.bottom = oldTop + (oEv.clientY + oldY) + ’px’; } } document.onmouseup = function(){ document.onmousemove = null; }; return false;} },

如果想看封裝的組件,請查看github地址:github地址

縮放效果如下圖:

vue基于Echarts的拖拽數據可視化功能實現

Echarts縮放中存在的問題

vue中使用echarts圖表自適應的幾種基本解決方案,此處不再進行贅述,詳情請參考如下鏈接:echarts圖表自適應

結束語

本文只是粗略的記錄了數據可視化簡單demo的實現思路,如果您覺得對您有幫助,請下載源碼 github地址

喜歡的小伙伴給個star,謝謝

參考文獻

https://www.jb51.net/article/201371.htm

https://www.jb51.net/article/201349.htm

到此這篇vue基于Echarts的拖拽數據可視化功能實現的文章就介紹到這了,更多相關vue基于Echarts拖拽數據可視化內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产高潮在线| 亚洲精品小说| 亚洲精品九九| 亚洲精品福利| 日本午夜精品一区二区三区电影| 欧美久久一区二区三区| 国产精品三级| 91日韩免费| 精品中文一区| 四虎国产精品免费久久| 日韩美女精品| 精品国产不卡一区二区| 麻豆国产欧美一区二区三区| 国产成人精品亚洲线观看| 久久久噜噜噜| 日韩精品导航| 欧美国产一级| 日韩亚洲国产欧美| 国产麻豆一区二区三区精品视频| 国产一区二区亚洲| 亚洲精品一二三区区别| 天海翼精品一区二区三区| 国产精品巨作av| 日韩另类视频| 亚洲免费毛片| 丝袜诱惑一区二区| 久久最新视频| 久久一区视频| 亚洲免费播放| 国产欧美高清视频在线| 久久婷婷丁香| 国产精品最新| 欧美日韩高清| 精品一区二区三区在线观看视频 | 美女性感视频久久| 色婷婷狠狠五月综合天色拍| 亚洲精品乱码日韩| 日本在线精品| 日韩精品免费视频人成| 亚洲性图久久| 国产精品红桃| 老鸭窝毛片一区二区三区| 久久影院一区二区三区| 99在线精品视频在线观看| 欧美精品成人| 亚洲视频电影在线| 日韩精品免费一区二区三区| 欧美视频一区| 国产精品日本| 色偷偷偷在线视频播放| 欧美一区二区三区久久精品| 亚洲小说欧美另类婷婷| 国产精品久久国产愉拍| 免费一级片91| 黄在线观看免费网站ktv| 日韩不卡一区二区三区| 亚洲精品一区二区在线看| 国产不卡av一区二区| 日韩精品a在线观看91| 欧美不卡视频| 国产网站在线| 免费在线日韩av| 欧美在线91| 日本欧洲一区二区| 美女少妇全过程你懂的久久| 中文在线а√天堂| 精品欧美日韩精品| 欧美a级一区二区| 国产日韩欧美高清免费| 99国产精品自拍| 99tv成人| 日本韩国欧美超级黄在线观看| 国产精品mm| 日韩在线电影| 蜜桃91丨九色丨蝌蚪91桃色| 国产主播一区| 日韩在线观看不卡| 快播电影网址老女人久久| 久久不卡国产精品一区二区| 日韩国产一二三区| 亚洲精品日本| 视频一区二区三区在线| 亚洲免费播放| 亚洲欧洲午夜| 久久精品高清| 欧美成人高清| 在线成人直播| 亚洲一区国产一区| 三级亚洲高清视频| 午夜在线精品| 蜜桃久久av一区| 中文字幕日韩欧美精品高清在线| 欧美综合二区| 丝袜脚交一区二区| 亚洲人亚洲人色久| 日韩1区2区3区| 国产精品一区二区三区四区在线观看| 日韩va欧美va亚洲va久久| 欧美日韩va| 国产亚洲一区| 久久影院资源站| 中文字幕人成乱码在线观看| 丝袜av一区| 99亚洲视频| 日韩激情中文字幕| 精品淫伦v久久水蜜桃| а√天堂8资源在线| 欧美亚洲在线日韩| 久久av在线| 国产调教一区二区三区| 精品国产亚洲一区二区三区在线| 欧美xxxx中国| 国产综合色产| 亚洲精品自拍| 国产精品羞羞答答在线观看| 久久精品国产久精国产爱| 岛国av在线播放| 欧美日韩激情| 色婷婷成人网| 国产精品日韩精品在线播放| 亚洲精品福利电影| 日韩中文字幕一区二区三区| 久久精品超碰| 亚洲人成在线网站| 在线国产精品一区| 卡一卡二国产精品| 成人av二区| 国产亚洲字幕| 日韩精品一区二区三区免费观看| 国产色综合网| 麻豆久久久久久| 欧洲毛片在线视频免费观看| 日韩午夜视频在线| 亚洲午夜天堂| 一区二区91| 国产精品毛片一区二区在线看| 精品中文字幕一区二区三区av| 91成人小视频| 99tv成人| 国产丝袜一区| 欧美99久久| 国产精品一国产精品| 久久蜜桃资源一区二区老牛| 日本a级不卡| 日韩精品水蜜桃| 日韩二区三区四区| 欧美成人精品| 精品三级久久久| 亚州精品视频| 日韩精品免费一区二区三区| 婷婷综合一区| 久久美女性网| 欧美黑人做爰爽爽爽| 91久久久久| а√在线中文在线新版| 日本不卡视频一二三区| 五月激情久久| 国产精品欧美大片| 亚洲欧美高清| 神马午夜在线视频| 国产精品中文| 亚洲精品免费观看| 国产一区久久| 97国产精品| 国产精品magnet| 综合色一区二区| 免费精品国产的网站免费观看| 精品中文在线| 国产精品一区二区三区av| 久久成人国产| 欧美精品羞羞答答| 国产色播av在线| 久久av影视| 日本强好片久久久久久aaa| 五月天综合网站| 国产精选在线| 精品亚洲精品| 欧美激情亚洲| 国产伦精品一区二区三区在线播放 | 男女男精品视频网| 久久久久国产精品一区二区| 久久精品亚洲| 国产视频一区二区在线播放| 一区二区三区午夜视频| 日韩免费福利视频| 国际精品欧美精品| 欧美91在线| 国产精品白丝一区二区三区| 日韩精品久久久久久| 亚洲日本在线观看视频| 噜噜噜躁狠狠躁狠狠精品视频 | 成人自拍av| 97人人精品| 欧美久久天堂| 精品久久精品| 国产一区二区精品福利地址| 精品一级视频| 成人国产精选| 精品亚洲自拍| 久久电影tv|