搭建大数据可视化平台(第二篇——搭建编辑器内核【一】)

·  阅读 624

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

前言

我又继续搭建大数据可视化平台了,上一期讲到的是整体项目的设计方案,有兴趣的可以去看一下。

  1. 搭建大数据可视化平台(第一篇——可视化平台方案)

这一篇我想给大家讲述怎么搭建一个编辑器内核,这个是我觉得这个项目中重点之一也是难点之一,所以我肝了几天代码,终于把它搭好了,头发都快没了,所以今天就来做一个总结。

先给大家看一下大概的效果,界面虽然有点丑陋哈,但是前期是一步一步搭起来的,希望大家能多支持支持。

Tab-1634451146900.gif

再给大家罗列一下需要实现哪些功能!然后再给大家讲怎么一步一步踩坑的。

  1. 可拖拽且自定义拉伸的模块组件
  2. 拖拽的模块组件支持显示参考线和对齐线
  3. 横纵坐标轴的标尺刻度线
  4. 标尺刻度线上的辅助线
  5. 可自由缩放的画布

1.可拖拽的模块组件

可视化平台就是必须支持用户随意拖拽模块进行定位与设置模块的大小和其他的配置信息。这一步我琢磨了很久,也看了很多类似的文章。

1.1 第一次掉入深渊

最开始用的是 vue-draggable,这个也是我之前用过的插件,介绍一下基本用法:

// 安装
npm i vuedraggable -S 

<template>
  <vuedraggable class="wrapper" v-model="list">
    <transition-group>
      <div v-for="item in list" :key="item" class="item">
        <p>{{item}}</p>
      </div>
    </transition-group>
  </vuedraggable>
</template>

<script>
import vuedraggable from 'vuedraggable';

export default {
  name: 'HelloWorld',
  components: {vuedraggable},
  props: {
  },
  data() {
    return {
      list: [1,2,34,4,54,5]
    }
  },
  updated() {
    console.log(this.list)
  },
  methods: {
  }
}
</script>
<style scoped>
.wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
}
.item{
  width: 300px;
  height: 50px;
  background-color: #42b983;
  color: #ffffff;
}
</style>

复制代码

image.png

基本能满足拖拽的功能,但是发现要拓展自定义拉伸大小与参考线和对齐线等功能,vue-draggable 就满足不了了我们想要的,所以建议不要使用vue-draggable,它使用的场景一般是拖拽排序,拖拽克隆这种简单的。

1.2 第二次接近完美

下面我又游历了各大网站,终于找到一个支持拖拽与自定义拉伸大小功能的插件 vue-draggable-resizable,介绍一下它的基本用法:

// 安装
npm install -S vue-draggable-resizable

<template>
<div class="bi-canvas-panel" :style="boxStyle">
    <vue-draggable-resizable 
    v-for="(item, index) in modules" 
    :key="index" 
    :x="item.x"
    :y="item.y" 
    :z="item.z" 
    :w="item.width" 
    :h="item.height"
    @deactivated="onDeactivated"
    @activated="onActivated"
    @dragging="onDrag" 
    @resizing="onResize" 
    :parent="true">
        <p>
        Hello! I'm a flexible cobi-mponent. You can drag me around and you can resize me.<br>
            X: {{ item.x }} / Y: {{ item.y }} - Width: {{ item.width }} / Height: {{ item.height
            }}</p>
    </vue-draggable-resizable>
</div>
</template>

<script>
import VueDraggableResizable from 'vue-draggable-resizable'
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'

export default {
  name: "HelloWorld",
  data: function() {
    return {
        // 组件模块信息
        modules: [
          {
            // 基本属性(宽度,高度,横向位置,纵向位置,层级)
            width: 500,
            height: 300,
            x: 0,
            y: 0,
            z: 0
          },
          {
            // 基本属性
            width: 500,
            height: 300,
            x: 0,
            y: 0,
            z: 0
          }
        ],
        activeIndex: null
    };
  },
  methods: {
    // 修改模块大小变化回调函数
    onResize: function (x, y, width, height) {
      const item = this.modules[this.activeIndex]
      item.x = x
      item.y = y
      item.width = width
      item.height = height
    },
    // 拖拽模块位置变化回调函数
    onDrag: function (x, y) {
      const item = this.modules[this.activeIndex]
      item.x = x
      item.y = y
    },
    // 触摸或者点击选中
    onActivated (index) {
      this.activeIndex = index
    },
    // 触摸或者点击厉害
    onDeactivated () {
      this.activeIndex = null
    }
  }
};
</script>
<style scoped>
.wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
}
.item{
  width: 300px;
  height: 50px;
  background-color: #42b983;
  color: #ffffff;
}
</style>
复制代码

给大家看一下完成后的效果:(图片有点模糊哈,可能是录制工具的问题了,有好的录制工具可以推荐给我哈,写博客真的太难了)

Tab-1633965785563.gif

完成了拖拽功能与自定义拉伸功能后(不要问我为什么不自己写,也不是写不出来,自己写可能会花费更多的时间,有那个时间干嘛不拿去刷刷掘金的文章呢😁😁),接下来就准备实现参考线和对齐线了。

2 实现拖拽模块的参考线和对齐线功能

2.1 实现拖拽模块的参考线功能

实现参考线就很简单了,实现原理:插件已经提供了x轴坐标与y轴坐标的值,那我们就直接用就好了。创建一个外层与父级大小一致,内置创建两条参考线(x轴与y轴),使用相对定位在外层的左上角即可。

<template>
<div class="bi-canvas-panel" :style="boxStyle">
    <vue-draggable-resizable 
    v-for="(item, index) in modules" 
    :key="index" 
    :x="item.x"
    :y="item.y" 
    :z="item.z" 
    :w="item.width" 
    :h="item.height"
    @deactivated="onDeactivated"
    @activated="onActivated"
    @dragging="onDrag" 
    @resizing="onResize" 
    :parent="true">
    <div class="bi-nav-line" v-show="activeIndex == index && auxiliaryFn.isReferenceLine">
        <div class="bi-nav-line-top" :style="{height: (item.y + 1000) + 'px'}"></div>
        <div class="bi-nav-line-left" :style="{width: (item.x + 1000) + 'px'}"></div>
        <div class="bi-nav-line-account">{{ item.x}}, {{ item.y}}</div>
    </div>
        <p>
        Hello! I'm a flexible cobi-mponent. You can drag me around and you can resize me.<br>
            X: {{ item.x }} / Y: {{ item.y }} - Width: {{ item.width }} / Height: {{ item.height
            }}</p>
    </vue-draggable-resizable>
</div>
</template>
复制代码

给大家看一下完成后的效果:(图片有点模糊哈,可能是录制工具的问题了,有好的录制工具可以推荐给我哈,写博客真的太难了)

Tab-1634448548451.gif

2.1 实现拖拽模块的对齐线功能

实现对齐线也很简单,vue-draggable-resizable中文说明文档官网上有对应的示例,我们直接拿过来用就好了。看以下代码:

<template>
<div class="bi-canvas-panel" :style="boxStyle">
    <vue-draggable-resizable 
    v-for="(item, index) in modules" 
    :key="index" 
    :x="item.x"
    :y="item.y" 
    :z="item.z" 
    :w="item.width" 
    :h="item.height"
    @deactivated="onDeactivated"
    @activated="onActivated"
    @dragging="onDrag" 
    @resizing="onResize" 
    :parent="true">
    <div class="bi-nav-line" v-show="activeIndex == index && auxiliaryFn.isReferenceLine">
        <div class="bi-nav-line-top" :style="{height: (item.y + 1000) + 'px'}"></div>
        <div class="bi-nav-line-left" :style="{width: (item.x + 1000) + 'px'}"></div>
        <div class="bi-nav-line-account">{{ item.x}}, {{ item.y}}</div>
    </div>
        <p>
        Hello! I'm a flexible cobi-mponent. You can drag me around and you can resize me.<br>
            X: {{ item.x }} / Y: {{ item.y }} - Width: {{ item.width }} / Height: {{ item.height
            }}</p>
    </vue-draggable-resizable>
<!--辅助线-->
<span class="ref-line v-line"
      v-for="(item, index) in vLine"
      v-show="item.display && auxiliaryFn.isAlignmentLine"
      :key="'v-line' + index + item.position"
      :style="{ left: item.position, top: '-25%', height: '150%'}"
></span>
<span class="ref-line h-line"
      v-for="(item, index) in hLine"
      :key="'h-line' + index + item.position"
      v-show="item.display && auxiliaryFn.isAlignmentLine"
      :style="{ top: item.position, left: '-25%', width: '150%'}"
></span>
</div>
</template>
<script>
import VueDraggableResizable from 'vue-draggable-resizable'
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'

export default {
  name: "HelloWorld",
  data: function() {
    return {
        vLine: [],
        hLine: []
    };
  },
  methods: {
    ```
    // 辅助线回调事件
    getRefLineParams (params) {
      const { vLine, hLine } = params
      this.vLine = vLine
      this.hLine = hLine
    }
  }
};
</script>
复制代码

你以为这样就好了吗?

当我以后我这样就好了,运行起来的时候,发现说好的对齐线不生效了,这下我就懵了,检查了官网的写法和我的代码写法,发现并没什么问题,但是怎么会出错呢?一开始以为版本问题。然后我就安装vue-draggable-resizable插件的其他版本,试了好多个版本也没有这个功能。我就怀疑是不是官网写错了呀。找了好多个版本都说有,被逼无奈下,查看了源码,经期发现源码里面并没有这个功能,我崩溃了,怎么会呢?官网说有的呀。无奈之下借鉴度娘的力量了,终于被我发现了问题所在,原来vue-draggable-resizable插件是有两个版本的,一个是vue-draggable-resizable、一个是vue-draggable-resizable-gorkysvue-draggable-resizable-gorkys是有这个功能,而我之前下的是没有的,中文说明文档也是按照vue-draggable-resizable-gorkys插件上功能来写的。这个问题看了半天,真的崩溃。先给大家看一下效果吧。

Tab-1634448830068.gif

这里有一个故事

vue-draggable-resizable是国外的一名程序员,名叫mauricius开发的,然后其中有一个程序员,名叫gorkys的用了这个插件,发现这个插件不能满足( 组件之间的冲突检测(不允许组件之间重叠)组件与组件之间进行对齐(类似于吸附效果)) 两个功能,于是gorkys就从mauricius开发的插件vue-draggable-resizable分支上,把代码拉到本地上,然后就加工改造添加了这两个功能并优化了文档说明,最后把自己的代码上传到自己的github。真的是自己动手、丰衣食足。

这两个插件的地址:

vue-draggable-resizable原组件地址:vue-draggable-resizable
vue-draggable-resizable-gorkys新组件地址:vue-draggable-resizable

建议

这里我建议大家用vue-draggable-resizable-gorkys这个插件,毕竟功能比较完整,或者大家也可以跟他一样,直接拉代码上手改,这样也行,哈哈哈。还有一个就是这个官网地址也分享给大家,快速入门

搭建编辑器内核的第一期我们先讲到这里,一边肝代码一边肝文档,真的不容易。如果大家各位觉得那里做的不好的或者有什么好的建议可以在下面评论告诉我,然后不要忘记动动你们宝贵的手指点一下赞,感谢感谢,下一期我也会肝出来的。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改