antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本  低版本和高版本

  我这里是使用的2.0版本 并且搭配了相关插件 例如:画布的图形变换、地图等

  个人推荐 2.0版本,高版本配置多,可使用相关插件多,但是文档描述小,仍在更新, 低版本文档描述清晰,但是相关插件少

二、antv x6 支持自定义节点! 

          这里要特别注意  虽然支持自定义节点,但是连线,连线桩也自然只能节点之间互连,所以你看我的例子中,想要列表里的子节点也可以实现 互相连接,但是这是自定义节点无法做到的。
          因为此时这一整个盒子就是 一个节点!

三、事件集合

    // 事件集合loadEvents(containerRef) {// 节点双击this.graph.on('node:dblclick', ({ node }) => {const data = node.store.data;console.log(data);this.$router.push({path: '/modeling/homeModeling',query: {id: data.modelingId,name: data.name,layerTypeId: data.layerTypeId,tableType: data.modelingType,},});});// 连线双击this.graph.on('edge:dblclick', ({ edge }) => {// const data = edge.store.data;// const { type, id } = data;// alert('连线双击');// console.log('edge:dbclick', edge);// if (type === 'taskNode') {//   this.nodeId = id;//   this.showRight = true;// } else {//   this.nodeId = '';//   this.showRight = false;// }});// 节点鼠标移入this.graph.on('node:mouseenter',FunctionExt.debounce(({ node }) => {// 添加删除// const x = node.store.data.size.width - 10;// node.addTools({//   name: 'button-remove',//   args: {//     x: 0,//     y: 0,//     offset: { x, y: 15 },//   },// });}),500,);this.graph.on('node:port-contextmenu', ({ e }) => {// console.log(//   'ports',//   e,//   e.currentTarget.parentElement.getAttribute('port'),// );});// 连接线鼠标移入this.graph.on('edge:mouseenter', ({ edge }) => {// edge.addTools([//   'source-arrowhead',//   'target-arrowhead',//   {//     name: 'button-remove',//     args: {//       distance: '50%',//     },//   },// ]);});// 节点鼠标移出this.graph.on('node:mouseleave', ({ node }) => {// // 移除删除// node.removeTools();});this.graph.on('edge:mouseleave', ({ edge }) => {// edge.removeTools();});this.graph.on('edge:connected', ({ isNew, edge }) => {// console.log('connected', edge.source, edge.target);// if (isNew) {//   // 对新创建的边进行插入数据库等持久化操作// }});},

四、画布初始化

    graphInit() {// 容器生成图表const containerRef = this.$refs.containerRef;const graph = new Graph({container: containerRef,background: {color: '#F1F6F9',},grid: {size: 10, // 网格大小 10pxvisible: true, // 绘制网格,默认绘制 dot 类型网格type: 'fixedDot',args: {color: '#AFB0B1', // 网点颜色thickness: 1, // 网点大小},},panning: true, // 画布拖拽history: true, // 启动历史记录selecting: {// 选择与框选enabled: true,rubberband: true,movable: true,strict: true,showNodeSelectionBox: true, // 显示节点的选择框(才能进行移动)modifiers: ['alt'],},// Scroller 使画布具备滚动、平移、居中、缩放等能力scroller: {enabled: true,pageVisible: true,pageBreak: true,pannable: true,},// 鼠标滚轮的默认行为是滚动页面 使用ctrl+滚轮 实现缩放mousewheel: {enabled: true,modifiers: ['ctrl', 'meta'], // +按键为缩放minScale: 0.5,maxScale: 2,},snapline: true, // 对齐线// 节点连接connecting: {router: {name: 'er',args: {offset: 25,direction: 'H',},},snap: true, // 自动吸附allowBlank: false, // 是否允许连接到画布空白位置的点allowLoop: false, // 是否允许创建循环连线,即边的起始节点和终止节点为同一节点allowNode: false, // 是否允许边链接到节点(非节点上的链接桩)createEdge() {return new Shape.Edge({attrs: {line: {stroke: '#1684FC',strokeWidth: 2,},},});},},// 连接桩样式 -- 高亮highlighting: {magnetAvailable: {name: 'stroke',args: {padding: 4,attrs: {strokeWidth: 4,stroke: '#1684FC',},},},},});// 小地图const minimapContainer = this.$refs.minimapContainer;graph.use(new MiniMap({container: minimapContainer,width: '250',height: '150',scalable: true, // 是否可缩放minScale: 0.01,maxScale: 16,}),);// 图形graph.use(new Transform({enabled: true,resizing: map,}),);// 缩放画布内容,使画布内容充满视口graph.zoomToFit({ padding: 10, maxScale: 1 });// 赋值生成this.graph = graph;// 事件集合this.loadEvents(containerRef);},

五、创建Vue自定义节点

<template><divref="node_dom"class="node_warp":style="{width: node.size.width + 'px',height: node.size.height + 'px',borderTopColor: color,}"><div class="head_top" :style="{ backgroundColor }"><svg-icon :icon-class="icon" :style="{ color }"></svg-icon><div class="code_warp"><span class="code ellipsis_text">{{ node.code }}</span><span class="name ellipsis_text">{{ node.name }}</span></div><el-popoverref="popoverDom"placement="bottom-end"width="60":value="popShow"trigger="click"popper-class="filter_column_popover"@hide="popShow = false"@show="popShow = true"><svg-iconslot="reference"class="icon"type="primary"size="mini"style="opacity: 0.5;"icon-class="table_column_settings"></svg-icon><p class="header_wrap_filter_column"><el-checkboxv-model="checkAll":indeterminate="isIndeterminate"@change="handleCheckAllChange">全选</el-checkbox><!-- --><!-- <el-button size="mini" type="text" @click="resetColumn">重置</el-button> --></p><el-checkbox-groupv-model="checkList"@change="handleCheckedCitiesChange"><el-checkbox v-for="item in checkData" :key="item" :label="item">{{ item }}</el-checkbox></el-checkbox-group><div v-if="!checkData.length" class="empy">暂无数据</div></el-popover></div><div class="main"><divv-for="(item, index) in node.columnVersions":key="index"class="text "><svg-icon v-if="item.isPrimaryKey" icon-class="key"></svg-icon><span v-show="checkList.includes('英文名称')" class="ellipsis_text">{{ item.code }}</span><div v-show="checkList.includes('字段类型')" class="type ellipsis_text">{{ item.dataType }}</div><span v-show="checkList.includes('中文名称')" class="ellipsis_text">{{ item.name }}</span></div><divv-if="!node.columnVersions || !node.columnVersions.length"class="empy flex">暂无数据</div></div><div class="footer">{{ `共${node.columnSize || 0}个字段` }}</div></div>
</template><script>
import { manage } from './config';
const cityOptions = ['英文名称', '字段类型', '中文名称'];
export default {name: 'Node',inject: ['getNode'],data() {return {num: 0,icon: '',color: '',node: {},popShow: false,checkAll: false,checkList: ['英文名称', '字段类型'],checkData: cityOptions,isIndeterminate: true,backgroundColor: null,typeMap: manage.typeMap,};},watch: {checkList(val) {console.log(val);},},created() {const node = this.getNode();const typeMap = this.typeMap;this.node = node.store.data;const type = this.node.modelingType;this.icon = typeMap[type].icon;this.color = typeMap[type].color;this.backgroundColor = typeMap[type].backgroundColor;},methods: {handleCheckAllChange(val) {this.checkList = val ? cityOptions : [];this.isIndeterminate = false;},handleCheckedCitiesChange(value) {const checkedCount = value.length;this.checkAll = checkedCount === this.checkData.length;this.isIndeterminate =checkedCount > 0 && checkedCount < this.checkData.length;},resetColumn() {this.checkList = ['英文名称', '字段类型'];},},
};
</script><style lang="scss" scoped>
.node_warp {display: flex;border-radius: 4px;flex-direction: column;border: 1px solid #d9dae2;border-top: 5px solid #d9dae2;position: relative;user-select: none;transition: all 0.4s ease-in 0.2s;transition: width 0.25s;-webkit-transition: width 0.25s;-moz-transition: width 0.25s;-webkit-transition: width 0.25s;-o-transition: width 0.25s;.head_top {width: 100%;height: 48px;display: flex;padding-left: 10px;align-items: center;position: relative;border-bottom: 1px solid #d9dae2;.code_warp {width: 85%;font-size: 12px;margin-left: 8px;display: flex;flex-direction: column;.code {color: black;font-weight: 700;}.name {color: #b3b2bf;font-weight: 600;}}.icon {position: absolute;right: 5px;bottom: 5px;}}.main {flex: 1;width: 100%;overflow: auto;padding-right: 2px;background: #fff;.text {height: 32px;display: flex;gap: 1px;font-size: 13px;position: relative;padding-left: 20px;align-items: center;svg {position: absolute;left: 4px;top: 10px;}.type {flex: 1;height: 24px;font-size: 12px;line-height: 24px;text-align: center;border-radius: 4px;margin-right: 5px;display: inline-block;background-color: #f7f7f9;}span {flex: 1;text-align: center;}&:hover {background: #f8f8fa;}}}.footer {height: 20px;font-size: 12px;line-height: 20px;padding-left: 10px;color: rgb(156, 160, 184);border-top: 1px solid #d9dae2;background: rgb(247, 247, 249);}.ellipsis_text {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;word-break: break-all;line-height: 18px;}.empy {color: #ccc;font-size: 14px;margin: 10px auto;width: fit-content;}.flex {display: flex;height: calc(100% - 30px);align-items: center;}
}
</style>

六、注册引入Vue自定义节点

1、安装依赖

      "@antv/x6-vue-shape": "2.0.6",

      yarn add antv/x6-vue-shape@2.0.6

2、引入 Vue 自定义组件

      import CustomNode from '../node';

3、引入插件的方法

      import { register } from '@antv/x6-vue-shape'; // vue节点

4、注册节点

        

register({

  shape: 'custom-vue-node',

  component: CustomNode,

});


import CustomNode from '../node';
import { register } from '@antv/x6-vue-shape'; // vue节点// 注册 Vue component
register({shape: 'custom-vue-node',component: CustomNode,
});

七、创建节点、创建连线、渲染节点

// 连接线  
const lineNewData = newData.map((item, index) => {return {id: String(new Date().getTime() + index),shape: 'edge',// 连接源source: {cell: item.sourceTableId,},// 连接目标target: {cell: item.targetTableId,},attrs: {line: {stroke: '#1684FC',strokeWidth: 2,},},// 名字labels: [{attrs: {label: {text: item.name || '',},},},],zIndex: 0,};});// 节点const nodeData = result.map(item => {return {...item,id: item.modelingVersionId,width: Number(item.width || 300),height: Number(item.heigh || 270),// 节点类型shape: item.shape || 'custom-vue-node',position: {x: Number(item.posX || this.getRandomInt()),y: Number(item.posY || this.getRandomInt()),},};});this.erData = [...nodeData, ...lineNewData];

  通过数据 渲染节点

  watch: {data(val) {const cells = [];this.data.forEach(item => {console.log(item, item.shape);if (item.shape === 'edge') {cells.push(this.graph.createEdge(item)); // 创建连线} else {cells.push(this.graph.createNode(item)); // 创建节点}});// 清空画布并添加用指定的节点/边this.graph.resetCells(cells);},},

八、canvas主页面 全部代码

<template><div id="container" class="antv-x6"><div ref="minimapContainer" class="app-mini"></div><div ref="containerRef" class="app-content"></div><div class="operating"><el-selectv-model="value"clearablefilterableplaceholder="请选择"size="mini":popper-append-to-body="false":class="isShow ? 'showSelect' : 'hideSelect'"@change="valChange"><el-optionv-for="item in data.filter(i => i.modelingType)":key="item.id":label="item.code":value="item.id"><div class="head_top"><svg-icon:icon-class="typeMap[item.modelingType].icon":style="{ color: typeMap[item.modelingType].color }"/><div class="code_warp"><span class="code ellipsis_text">{{ item.code }}</span><span class="name ellipsis_text">{{ item.name }}</span></div></div></el-option></el-select><div class="icon_oper"><el-tooltipclass="item"effect="dark"content="搜索"placement="bottom"><svg-icon icon-class="search_canvas" @click="search" /></el-tooltip><el-tooltipclass="item"effect="dark"content="放大"placement="bottom"><svg-icon icon-class="amplify_canvas" @click="zoomInFn" /></el-tooltip><el-tooltipclass="item"effect="dark"content="缩小"placement="bottom"><svg-icon icon-class="reduce_canvas" @click="zoomOutFn" /></el-tooltip><el-tooltipclass="item"effect="dark"content="还原"placement="bottom"><svg-icon icon-class="1_1_canvas" @click="resetFn" /></el-tooltip><el-tooltipclass="item"effect="dark"content="保存"placement="bottom"><svg-icon icon-class="saveModel" @click="submit" /></el-tooltip><el-tooltipclass="item"effect="dark":content="isFullScreen ? '退出全屏' : '全屏'"placement="bottom"><svg-icon icon-class="screen" @click="fullScreen" /></el-tooltip><el-tooltipclass="item"effect="dark"content="刷新"placement="bottom"><svg-icon icon-class="refresh" @click="redoFn" /></el-tooltip></div></div></div>
</template><script>
import { manage } from '../config';
import CustomNode from '../node';
import { Graph, Shape, FunctionExt } from '@antv/x6';
import { register } from '@antv/x6-vue-shape'; // vue节点
import { MiniMap } from '@antv/x6-plugin-minimap'; // 地图
import { Transform } from '@antv/x6-plugin-transform'; // 图形变换
// import { Scroller } from '@antv/x6-plugin-scroller'; // 滚动画布const map = {enabled: true,minWidth: 200,maxWidth: 700,minHeight: 100,maxHeight: 500,orthogonal: false,restrict: false,preserveAspectRatio: false,
};// 注册 Vue component
register({shape: 'custom-vue-node',component: CustomNode,
});export default {name: 'Er',props: {data: {type: Array,default: () => [],},},data() {return {value: '',graph: null,isShow: false,showRight: false,isFullScreen: false,typeMap: manage.typeMap,};},watch: {data(val) {const cells = [];this.data.forEach(item => {console.log(item, item.shape);if (item.shape === 'edge') {cells.push(this.graph.createEdge(item)); // 创建连线} else {cells.push(this.graph.createNode(item)); // 创建节点}});// 清空画布并添加用指定的节点/边this.graph.resetCells(cells);},},mounted() {this.graphInit();},methods: {graphInit() {// 容器生成图表const containerRef = this.$refs.containerRef;const graph = new Graph({container: containerRef,background: {color: '#F1F6F9',},grid: {size: 10, // 网格大小 10pxvisible: true, // 绘制网格,默认绘制 dot 类型网格type: 'fixedDot',args: {color: '#AFB0B1', // 网点颜色thickness: 1, // 网点大小},},panning: true, // 画布拖拽history: true, // 启动历史记录selecting: {// 选择与框选enabled: true,rubberband: true,movable: true,strict: true,showNodeSelectionBox: true, // 显示节点的选择框(才能进行移动)modifiers: ['alt'],},// Scroller 使画布具备滚动、平移、居中、缩放等能力scroller: {enabled: true,pageVisible: true,pageBreak: true,pannable: true,},// 鼠标滚轮的默认行为是滚动页面 使用ctrl+滚轮 实现缩放mousewheel: {enabled: true,modifiers: ['ctrl', 'meta'], // +按键为缩放minScale: 0.5,maxScale: 2,},snapline: true, // 对齐线// 节点连接connecting: {router: {name: 'er',args: {offset: 25,direction: 'H',},},snap: true, // 自动吸附allowBlank: false, // 是否允许连接到画布空白位置的点allowLoop: false, // 是否允许创建循环连线,即边的起始节点和终止节点为同一节点allowNode: false, // 是否允许边链接到节点(非节点上的链接桩)createEdge() {return new Shape.Edge({attrs: {line: {stroke: '#1684FC',strokeWidth: 2,},},});},},// 连接桩样式 -- 高亮highlighting: {magnetAvailable: {name: 'stroke',args: {padding: 4,attrs: {strokeWidth: 4,stroke: '#1684FC',},},},},});// 小地图const minimapContainer = this.$refs.minimapContainer;graph.use(new MiniMap({container: minimapContainer,width: '250',height: '150',scalable: true, // 是否可缩放minScale: 0.01,maxScale: 16,}),);// 图形graph.use(new Transform({enabled: true,resizing: map,}),);// 缩放画布内容,使画布内容充满视口graph.zoomToFit({ padding: 10, maxScale: 1 });// 赋值生成this.graph = graph;// 事件集合this.loadEvents(containerRef);},// 事件集合loadEvents(containerRef) {// 节点双击this.graph.on('node:dblclick', ({ node }) => {const data = node.store.data;console.log(data);this.$router.push({path: '/modeling/homeModeling',query: {id: data.modelingId,name: data.name,layerTypeId: data.layerTypeId,tableType: data.modelingType,},});});// 连线双击this.graph.on('edge:dblclick', ({ edge }) => {// const data = edge.store.data;// const { type, id } = data;// alert('连线双击');// console.log('edge:dbclick', edge);// if (type === 'taskNode') {//   this.nodeId = id;//   this.showRight = true;// } else {//   this.nodeId = '';//   this.showRight = false;// }});// 节点鼠标移入this.graph.on('node:mouseenter',FunctionExt.debounce(({ node }) => {// 添加删除// const x = node.store.data.size.width - 10;// node.addTools({//   name: 'button-remove',//   args: {//     x: 0,//     y: 0,//     offset: { x, y: 15 },//   },// });}),500,);this.graph.on('node:port-contextmenu', ({ e }) => {// console.log(//   'ports',//   e,//   e.currentTarget.parentElement.getAttribute('port'),// );});// 连接线鼠标移入this.graph.on('edge:mouseenter', ({ edge }) => {// edge.addTools([//   'source-arrowhead',//   'target-arrowhead',//   {//     name: 'button-remove',//     args: {//       distance: '50%',//     },//   },// ]);});// 节点鼠标移出this.graph.on('node:mouseleave', ({ node }) => {// // 移除删除// node.removeTools();});this.graph.on('edge:mouseleave', ({ edge }) => {// edge.removeTools();});this.graph.on('edge:connected', ({ isNew, edge }) => {// console.log('connected', edge.source, edge.target);// if (isNew) {//   // 对新创建的边进行插入数据库等持久化操作// }});},// 放大zoomInFn() {this.graph.zoom(0.1);},// 缩小zoomOutFn() {const Num = Number(this.graph.zoom().toFixed(1));if (Num > 0.1) {this.graph.zoom(-0.1);}},// 重置1:1resetFn() {this.graph.centerContent();this.graph.zoomTo(1); // 缩放画布到指定的比例},// 刷新redoFn() {this.$emit('detailsEr');},// 全屏fullScreen() {// const element = document.documentElement;const element = document.getElementById('container');// 判断是否已经是全屏if (this.isFullScreen) {// 退出全屏if (document.exitFullscreen) {document.exitFullscreen();} else if (document.webkitCancelFullScreen) {document.webkitCancelFullScreen();} else if (document.mozCancelFullScreen) {document.mozCancelFullScreen();} else if (document.msExitFullscreen) {document.msExitFullscreen();}} else {// 全屏if (element.requestFullscreen) {element.requestFullscreen();} else if (element.webkitRequestFullScreen) {element.webkitRequestFullScreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.msRequestFullscreen) {// IE11element.msRequestFullscreen();}}this.isFullScreen = !this.isFullScreen;},// 搜索search() {this.isShow = !this.isShow;},// 保存submit() {const data = this.graph.getNodes();this.$emit('submitEr', data);},// 检索valChange(val) {if (val) {// false - 清空const nodes = this.graph.getNodes() || [];const node = nodes.filter(item => item.id === val)[0] || {};this.graph.centerCell(node); // 将节点/边的中心与视口中心对齐} else {this.resetFn();}},},
};
</script><style lang="scss" scoped>
.antv-x6 {width: 100%;height: 100%;padding: 0;display: flex;position: relative;box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;::v-deep body {min-width: auto;}.node-c {width: 200px;border-right: 1px solid #eee;padding: 20px;dl {margin-bottom: 20px;line-height: 30px;display: flex;cursor: move;dt {&.circle {width: 30px;height: 30px;border-radius: 50%;&.start {border: 1px solid green;background: greenyellow;}&.end {border: 1px solid salmon;background: red;}}&.rect {width: 30px;height: 30px;border: 1px solid #ccc;}}dd {font-size: bold;font-size: 14px;padding: 0 0 0 10px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}}}.template-c {padding: 10px 0;li {line-height: 40px;font-size: 14px;border-bottom: 1px solid #dcdfe6;cursor: pointer;display: flex;justify-content: space-between;span {flex: 1;padding-right: 10px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}i {font-size: 14px;color: #2d8cf0;width: 20px;line-height: 40px;}}}.container {flex: 1;}.operating {position: absolute;z-index: 999;right: 20px;top: 10px;padding: 5px 10px;border-radius: 6px;background-color: #ffffff;border: 1px solid rgb(187, 187, 187);box-shadow: 1px 1px 4px 0 #0a0a0a2e;display: flex;height: 34px;align-items: center;.el-select {transition: width 0.6s ease-in-out;::v-deep .el-input__inner {height: 26px;line-height: 26px;}::v-deep .el-input--mini .el-input__icon {line-height: 26px;}::v-deep .el-select-dropdown__item {height: 48px;max-width: 410px;line-height: 48px;}&.hideSelect {width: 0px;::v-deep .el-input__inner {display: none;}::v-deep .el-input__suffix {display: none;}}&.showSelect {width: 180px;::v-deep .el-input__inner {display: block;}::v-deep .el-input__suffix {display: block;}}}.icon_oper {svg {font-size: 18px;cursor: pointer;margin: 0 5px;&:hover {color: #2d8cf0;}&.opacity {opacity: 0.5;}}}}
}
.app-mini {position: fixed;z-index: 999;bottom: 10px;right: 20px;border-radius: 6px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.app-content {flex: 1;height: 100% !important;
}
::v-deep .x6-graph-scroller {border: 1px solid #f0f0f0;margin-left: -1px;width: 100% !important;height: 100% !important;
}.head_top {width: 100%;height: 48px;display: flex;align-items: center;.code_warp {width: 90%;height: 100%;font-size: 12px;margin-left: 8px;display: flex;gap: 4px;flex-direction: column;justify-content: center;.code {color: black;font-weight: 700;line-height: normal;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;word-break: break-all;}.name {color: #b3b2bf;font-weight: 600;line-height: normal;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;word-break: break-all;}}
}
::v-deep .text {height: 32px;display: flex;gap: 1px;font-size: 13px;position: relative;padding-left: 20px;align-items: center;svg {position: absolute;left: 4px;top: 10px;}.type {width: 25%;height: 24px;font-size: 12px;line-height: 24px;text-align: center;border-radius: 4px;margin-right: 5px;display: inline-block;background-color: #f7f7f9;}span {flex: 1;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;word-break: break-all;line-height: 18px;}&:hover {background: #f8f8fa;}
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/714164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

装饰器模式 详解 设计模式

装饰器模式 它允许你在不改变对象结构的情况下&#xff0c;动态地将新功能附加到对象上。 结构&#xff1a; 抽象组件&#xff08;Component&#xff09;&#xff1a;定义了原始对象和装饰器对象的公共接口或抽象类&#xff0c;可以是具体组件类的父类或接口。具体组件&…

如何在群晖Docker运行本地聊天机器人并结合内网穿透发布到公网访问

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&#xff0c;包括聊天机…

C# Socket通信从入门到精通(21)——TCP发送文件与接收文件 C#代码实现

1、前言 我们在开发上位机软件的过程中经常需要发送文件,本文就是介绍如何利用tcp客户端发送文件、tcp服务器端接收文件,而且本文介绍的方法可以自动发送一个文件夹下的所有子目录以及所有文件,经验来自于实际项目,具备非常有价值的参考意义! 2、发送文件以及C#代码 被发…

低密度奇偶校验码LDPC(八)——QC-LDPC译码器FPGA设计概要

往期博文 低密度奇偶校验码LDPC&#xff08;一&#xff09;——概述_什么是gallager构造-CSDN博客 低密度奇偶校验码LDPC&#xff08;二&#xff09;——LDPC编码方法-CSDN博客 低密度奇偶校验码LDPC&#xff08;三&#xff09;——QC-LDPC码概述-CSDN博客 低密度奇偶校验码…

node.js 用 xml2js.Parser 读 Freeplane.mm文件,生成测试用例.csv文件

Freeplane 是一款基于 Java 的开源软件&#xff0c;继承 Freemind 的思维导图工具软件&#xff0c;它扩展了知识管理功能&#xff0c;在 Freemind 上增加了一些额外的功能&#xff0c;比如数学公式、节点属性面板等。 编写 mm_xml2js_csv.js 如下 // 用 xml2js.Parser 读 F…

javaWebssh票据管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh票据管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模 式开发。开发环境为TOMCAT7.0,My…

C++ 快速排序快速选择

目录 1、75. 颜色分类 2、912. 排序数组 3、 215. 数组中的第K个最大元素 4、LCR 159. 库存管理 III 1、75. 颜色分类 思路&#xff1a;利用快速排序思路&#xff0c;使用三指针分块进行优化。 [0,left]——小于key[left1,right-1]——等于key[right,nums.size()]——大于k…

博途PLC 面向对象系列之“输送带控制功能块“(SCL代码)

这篇是面向对象系列之"输送带功能块"的封装,面向对象是系列文章,相关链接如下: 1、面向对象系列之找"对象" https://rxxw-control.blog.csdn.net/article/details/136150027https://rxxw-control.blog.csdn.net/article/details/1361500272、面向对象…

LeetCode 刷题 [C++] 第215题.数组中的第K个最大元素

题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 题目分析 根据题意分析&…

CleanMyMac X2024一款专为Mac用户设计的优化工具

亲爱的用户们&#xff0c;我们都知道电脑在长时间使用后会变得越来越慢&#xff0c;垃圾文件和无用的应用程序会占用我们的硬盘空间&#xff0c;让我们的电脑变得像蜗牛一样慢。但是&#xff0c;现在有一个解决方案可以让你的电脑重获新生&#xff0c;那就是CleanMyMac X&#…

第七十一天 漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

第71天 漏洞发现-Web框架中间件&联动&Goby&Afrog&Xray&Awvs&Vulmap 知识点&#xff1a; 1、Bup简单介绍&使用说明 2、Xray简单介绍&使用说明 3、AWWS简单介绍&使用说明 4、Goby简单介绍&使用说明 5、Afrog简单介绍&使用说明 6、…

泰迪智能科技企业数据挖掘平台使用场景

企业数据挖掘平台助力企业数据挖掘&#xff0c;数据挖掘平台也在多个领域发挥着重要的作用。 企业数据挖掘平台具有数据抓取、数据清洗、数据分析、机器学习等多项功能&#xff0c;广泛应用于企业的各个领域&#xff0c;包括&#xff1a;金融行业、医疗行业、交通领域、教育、制…

RunnerGo UI自动化测试脚本如何配置

RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块&#xff0c;覆盖了整个产品测试周期。 RunnerGo UI自动化基于Selenium浏览器自动化方案构建&#xff0c;内嵌高度可复用的测试脚本&#xff0c;测试团队无需复杂的代码编写即可开展低代码的自动化…

BetterDisplay Pro for Mac v2.0.11激活版:屏幕显示优化专家

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 软件下载&#xff1a;BetterDisplay Pro for Mac v2.0.11激活版下载 &#x1f50d; 精准校准&#xf…

Unity的相机跟随和第三人称视角

Unity相机跟随和第三人称视角 介绍镜头视角跟随人物方向进行旋转的镜头视角固定球和人的镜头视角 思路跟随人物方向进行旋转的镜头视角固定球和人的镜头视角 镜头旋转代码人物移动的参考代码注意 介绍 最近足球项目的镜头在做改动&#xff0c;观察了一下实况足球的视角&#x…

npm digital envelope routines::unsupported

问题描述&#xff1a;npm运行命令报错&#xff1a;digital envelope routines::unsupported 原因&#xff1a;node版本过高 解决方案&#xff1a;在运行命令之前加上 SET NODE_OPTIONS--openssl-legacy-provider && SET NODE_OPTIONS--openssl-legacy-provider &&a…

阿里云服务器免费6个月,居然又出了企业版

我之前收到了阿里云的免费6个月服务器&#xff0c;现在上面挂着一些网页。 由于带宽只有1M&#xff0c;所以用得不多。 今晚本来打算买台新服务器&#xff0c;发现阿里云6个月免费促销居然出了企业版。 之前只有一个版本。 我手头正好有资源&#xff0c;于是又免费来了一台服…

Eslint在Vscode中使用技巧的相关技巧

ps :该文章会详细记录构建一个脚手架遇到的问题&#xff0c;会持续更新&#xff0c;请定时查看 Eslint相关​ 在vscode中使用eslint插件 在vscode中用户配置没有开启eslint.enable 在vscode中工作区配置开启eslint.enable settings.json中没有做eslint相关配置 在编写的vue…

【QT】Qt Charts概述

目录 1 QtCharts模块 2 图表的主要组成部分 2.1 QChartView的功能 2.2 序列 2.3 坐标轴 2.4 图例 3 一个简单的QChart绘图程序 QtCharts是Qt提供的图表模块&#xff0c;在Qt5.7以前只有商业版才有Qt Charts&#xff0c;但是从Qt5.7开始&#xff0c;社区版本也包含了Qt C…

【MySQL】mvcc以及三个重要日志

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;【】数据库 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 MVCC关键概念&#xff1a; MVCC机制的优点&#xff1a; 三个重要的日志&#xff1a; 重做日志&#xff1a; 回滚日志&am…