X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG 图、ER 图、流程图、血缘图等应用。
最终效果图
1.安装
npm install @antv/x6 --save //x6主要包
- npm install @antv/x6-vue-shape //使用vue组件画图插件
复制代码- npm install @antv/x6-plugin-dnd //拖拽 添加元素图形插件
复制代码
2.直接上代码
dom元素 form.vue
- <template>
- <!-- 新增、编辑弹窗-->
- <el-dialog width="1200px" class="flow-dialog" top="5vh" title="实体编辑" :visible.sync="show" :append-to-body="true" :close-on-click-modal = "false" v-el-drag-dialog>
- <div class="content">
- <!--左侧工具栏-->
- <div class="stencil" >
- <p>流程编辑器</p>
- <span @mousedown="startDragToGraph(item, $event)" v-for="item in list" :key="item" @click="test(item)" class="percentage-value">
- <i style="margin-right: 5px;cursor: pointer;" class="el-icon-setting"/>
- <span class="percentage-content">{{ item }}</span>
- </span>
- </div>
- <div class="panel">
- <!--流程图工具栏-->
- <div class="toolbar">
- <el-button class="float-btn" icon="el-icon-s-claim" type="primary" @click="save()">保存</el-button>
- <el-button class="float-btn" icon="el-icon-s-home" type="danger" @click="show=false">退出</el-button>
- <el-button style="margin-left: 100px;" class="float-btn" icon="el-icon-s-tools" type="success" @click="">设置预览参数</el-button>
- <el-button class="float-btn" icon="el-icon-notebook-2" type="info" @click="">预览节点数据</el-button>
- <el-button class="float-btn" icon="el-icon-refresh" type="success" @click="">重算预览数据</el-button>
- </div>
- <!--流程图画板-->
- <div id="containerShape" />
- </div>
- </div>
- </el-dialog>
- </template>
复制代码 js部门
- <script>
- import elDragDialog from '@/directive/el-drag-dialog'
- import { register } from '@antv/x6-vue-shape'
- import { Graph,Shape} from "@antv/x6";
- import CustomNode from './CustomNode.vue'
- import { Dnd } from '@antv/x6-plugin-dnd'
- export default {
- directives: { elDragDialog },
- data() {
- return {
- show:false,
- list: ['数据查询', '横向连接', '追加合并', '分组汇总', '数据过滤','字段设置','输出'],
- graph:{}
- }
- },
- mounted() {
- const attrs = {
- circle: {
- r: 4,
- magnet: true,
- fill: '#fff',
- stroke: '#85A5FF',
- strokeWidth: 1,
- },
- };
- register({
- shape: 'custom-vue-node',
- component: CustomNode,
- width: 180,
- height: 40,
- // port默认不可见
- ports: {
- groups: {
- in: {
- position: {
- name:'left',
- args: {
- dx: -10,
- y: '50%',
- },
- },
- attrs: attrs
- },
- out: {
- position: {
- name:'right',
- args: {
- x: '100%',
- dx: 10,
- y: '50%',
- },
- },
- attrs: attrs
- },
- },
- },
- })
- },
- methods: {
- open() {
- this.show = true;
- this.$nextTick(() => {
- this.init("containerShape");
- });
- },
- init(id){
- const graph = new Graph({
- container: document.getElementById(id),
- width: 1000,
- height: 1000,
- connecting: {
- router: 'manhattan',
- anchor: 'center',
- connectionPoint: 'anchor',
- createEdge() {
- return new Shape.Edge({
- attrs: {
- line: {
- stroke: '#52c41a',
- strokeWidth: 1,
- strokeDasharray: 5,
- targetMarker: 'classic',
- style: {
- animation: 'ant-line 30s infinite linear',
- },
- },
- },
- zIndex: 0,
- })
- },
- }
- })
- graph.addNode({
- shape: 'custom-vue-node',
- x: 100,
- y: 100,
- ports: [{group: 'in'},{group: 'out'}],
- data:{
- percentage: 30
- }
- })
- this.graph = graph;
- },
- save() {
- this.graph.addNode({
- shape: 'custom-vue-node',
- x: 200,
- y: 300,
- ports: [{group: 'in'},{group: 'out'}],
- data:{
- percentage: '数据流程飒飒飒飒拉开阿斯兰的卡死了的科目来打开'
- }
- })
- },
- // 自定义一个拖拽方法,也可以单独封装成一个js文件(方便调用)
- // 这里直接写到vue文件的methods方法里了
- // 需求:未置灰的可以拖拽,置灰的无法拖拽即禁用状态
- startDragToGraph(item, e) {
- const node = this.graph.createNode({
- shape: 'custom-vue-node',
- x: 200,
- y: 300,
- ports: [{group: 'in'},{group: 'out'}],
- data:{
- percentage: item
- }
- });
- const dnd = new Dnd({
- target: this.graph,
- // ☆拖拽结束时,验证节点是否可以放置到目标画布中。
- validateNode: () => {
- console.log('成功拖拽至目标画布')
- },
- })
- dnd.start(node, e)
- },
- }
- }
- </script>
复制代码 css部门
- <style type="text/css">
- @keyframes ant-line {
- to {
- stroke-dashoffset: -1000
- }
- }
- </style>
- <style type="text/css" scoped>
- .flow-dialog ::v-deep .el-dialog__body{
- max-height: 85vh;
- padding: 0;
- }
- .toolbar ::v-deep .el-button--small{
- padding: 5px 10px;
- }
- .content {
- width: 1180px;
- height: 85vh;
- display: flex;
- }
- .stencil {
- width: 230px;
- height: 100%;
- position: relative;
- margin-right: 10px;
- border-right: 1px solid rgba(0, 0, 0, 0.08);
- box-sizing: border-box;
- text-align: center;
- }
- .stencil p{
- margin: 0;
- line-height: 37px;
- border-bottom: 1px solid #00000008;
- background-color: #f7f9fb;
- font-size: 14px;
- padding-left: 5px;
- text-align: left;
- }
- .panel {
- width: calc(100% - 230px);
- height: 100%;
- }
- .panel .toolbar {
- width: 100%;
- height: 38px;
- display: flex;
- align-items: center;
- background-color: #f7f9fb;
- border-bottom: 1px solid rgba(0, 0, 0, 0.08);
- }
- .panel #containerShape {
- width: 100%;
- height: calc(100% - 10px) !important;
- }
- .percentage-value{
- display: inline-block;
- width: max-content;
- background-color: #fff;
- border: 1px solid #c2c8d5;
- border-left: 4px solid #5F95FF;
- border-radius: 4px;
- box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
- padding: 8px;
- font-size: 16px;
- margin-top: 10px;
- text-align: left;
- }
- .percentage-content{
- width: 100px;
- max-width: 150px;
- overflow: hidden;
- font-size: 12px;
- display: inline-block;
- }
- </style>
复制代码 CustomNode.vue节点元素dom
- <template>
- <span class="percentage-value">
- <i style="margin-right: 5px;cursor: pointer;" @click="save()" class="el-icon-setting"/>
- <span class="percentage-content">{{ percentage }}%</span>
- <i @click="save()" class="el-icon-success data-start"/>
- </span>
- </template>
- <script>
- export default {
- inject: ['getNode'],
- data() {
- return {
- percentage: 50,
- }
- },
- mounted() {
- const cell = this.getNode();
- this.percentage = cell.data.percentage;
- },
- methods: {
- save(){
- console.log("点击成功")
- }
- }
- }
- </script>
- <style type="text/css" scoped>
- .percentage-value{
- display: inline-block;
- width: max-content;
- background-color: #fff;
- border: 1px solid #c2c8d5;
- border-left: 4px solid #5F95FF;
- border-radius: 4px;
- box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
- padding: 10px;
- font-size: 16px;
- }
- .percentage-content{
- width: 100px;
- max-width: 150px;
- overflow: hidden;
- font-size: 12px;
- display: inline-block;
- }
- .data-start{
- margin-right: 5px;
- margin-left: 10px;
- cursor: pointer;
- color: #6bcc00;
- }
- </style>
复制代码 相干官方文档x6.antv官网
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |