- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章vue基于Echarts的拖拽数据可视化功能实现由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
我司产品提出了一个需求,做一个数据基于Echars的可拖拽缩放的数据可视化,上网百度了一番,结果出现了两种结局,一种花钱买成熟产品(公司不出钱),一种没有成熟代码,只能自己写了,故事即将开始,敬请期待......。 不,还是先上一张效果图吧,请看...... 。
定义:当前元素在屏幕上占用的空间,如下图:
其中:
offsetHeight: 该元素在垂直方向上的占用的空间,单位为px,不包括margin.
offsetWidth:该元素在水平方向上的占用空间,单位为px,不包括margin.
offsetLeft: 该元素距离左侧并且是定位过(relative || absolute)的父元素内边框的距离。注意:如果父元素中没有一个是定位的,则是距离body元素的距离.
offsetTop:该元素距离顶部并且是定位过(relative || absolute)的父元素内边框的距离。注意:如果父元素中没有一个是定位的,则是距离body元素的距离.
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 class="grid-content bg-purple-light drag-resize-area" @drop.prevent="drop($event)" @dragover.prevent=""> <div style="height:300px;width:400px" 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地址 。
效果图如下:
此功能用到了上面提到的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地址 。
拖动效果如下图:
此功能用到了上面提到的 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地址 。
缩放效果如下图:
Echarts缩放中存在的问题 。
vue中使用echarts图表自适应的几种基本解决方案,此处不再进行赘述,详情请参考如下链接:echarts图表自适应 。
本文只是粗略的记录了数据可视化简单demo的实现思路,如果您觉得对您有帮助,请下载源码 github地址 。
喜欢的小伙伴给个star,谢谢 。
http://www.zzvips.com/article/209675.html 。
到此这篇vue基于Echarts的拖拽数据可视化功能实现的文章就介绍到这了,更多相关vue基于Echarts拖拽数据可视化内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://juejin.cn/post/6901793967281537038 。
最后此篇关于vue基于Echarts的拖拽数据可视化功能实现的文章就讲到这里了,如果你想了解更多关于vue基于Echarts的拖拽数据可视化功能实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在将过滤器从 vue 1 迁移到 vue 2 时遇到问题,我在这里完全创建了我需要的东西(突出显示与输入文本匹配的文本): Vue.component('demo-grid', { templa
我有一个在 vue 组件外部运行的函数。我想要将它返回的数据传递给vue组件中的数据。 function example(){ var item = 'item'
我正在尝试安装一个 Vue 插件,以便我可以使用选项管理一些 API 调用。我有一个 stocks.js 文件,我想从中进行 API 调用。 当我执行以下操作时,出现'Vue is defined b
如何从指令访问 Vue 实例? 我有这个 HTML 和这个脚本 var app = new Vue({ el: '#vueApp', data: { myData:
如何在 .vue 文件中使用 Vue.set() 和 Vue.use()?我正在使用 vue-cli 搭建我的项目,我需要使用 Vue.use(VeeValidate) 进行验证。我也想使用类似下面的
从 vue-property-decorator 和 vue 导入 Vue 之间有什么区别和用例?据我所知,在使用 @Component 装饰器定义自定义组件时,我始终需要从 vue-property
有没有办法使用 yarn serve(可能使用 webpack/vuetify-loader)在本地 Vuetify 应用程序的本地 npm 依赖项上发生热重载? 商业案例 我们有一些通用的 Vuet
我有一个在某些未知情况下不可靠的插槽的奇怪错误。 成分 有3个层次组件。 孙子 (headlessTable),它提供一个名为 arrayValue 的插槽. 子项 (collapsableCard)
我是 Vue 本地新手,我也遇到了一个问题,can I use the Vue component inside a Vue native component such as Vue-chart an
Vue.delete 的替代方案是什么?在 Vue 3 的新 Reactivity API 中? 最佳答案 Vue.delete和 Vue.set在 Vue 3 中不需要。通过使用代理的新 react
我是 Vue 的新手,正在尝试学习如何使用它。 我想我在尝试安装一个新的 Vue 应用程序时被绊倒了。 这是我可以开始工作的内容: const vm = new Vue({}) 从那里我可以安装
我使用boots-vue。我从文档https://bootstrap-vue.js.org/docs/components/table/#table-body-transition-support中举
我真的只是想为我的图书馆建立一个 jest+vue 的框架,并迅速得到这个错误。 我知道这个结构不是通常的笑话结构,我在这里尝试用一个辅助控件来描述一个测试。 这是我的test的内容文件夹:array
我正在尝试使用基于 examples 的 vue-router , 如 let routes = [ { path: '/', component: MainComponent }, ];
我有一个想要通过简单的 v-model 功能发布到 NPM 的组件。 因此,如果它能够在 vuejs 2/3 上互换运行那就更理想了。 我可以通过将组件设置为发出 input 和 update:mod
我正在尝试在 bootstrap-vue 表中创建一个插槽,以使用自定义组件呈现任何 bool 值。 所以我有一个简单的表格 现在,如果我想以特定方式渲染单个列,我必须使用插槽 它有
Vue Router 在主 Vue 实例之前加载,但要加载该 Router,我应该准备一些信息,然后将它们作为属性传递给此 Route。在此示例中,它是从主 Vue 实例传递到主屏幕的 current
我有一个想要通过简单的 v-model 功能发布到 NPM 的组件。 因此,如果它能够在 vuejs 2/3 上互换运行那就更理想了。 我可以通过将组件设置为发出 input 和 update:mod
我找到了一个关于如何使用 Vue 路由器的很好的例子。这是 app.js 文件: // Telling Vue to use the router Vue.use(VueRouter) // Init
我没有完整的 vue 应用程序,所以我使用 custom elements替换一些应该用 vue 处理的元素。 我只想使用 vue multiselect plugin在 html 文件中。 所以我尝
我是一名优秀的程序员,十分优秀!