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

news/2024/4/16 16:16:49/文章来源:https://blog.csdn.net/xiaoleiv9/article/details/136397606

一、 首先 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.luyixian.cn/news_show_996992.aspx

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

相关文章

(正规api接口代发布权限)短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态

短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态源头开发&#xff08;本篇禁止抄袭复刻&#xff09; 一、短视频矩阵系统开发者架构 云罗短视频矩阵系统saas化系统&#xff0c;开发层将在CAP原则基础上使用分布式架构,对此网站的整体架构采用了基于B/S三层架构模式…

R语言数据可视化之美专业图表绘制指南(增强版):第1章 R语言编程与绘图基础

第1章 R语言编程与绘图基础 目录 第1章 R语言编程与绘图基础前言1.1 学术图表的基本概念1.1.1 学术图表的基本作用1.1.2基本类别1.1.3 学术图表的绘制原则 1.2 你为什么要选择R1.3 安装 前言 这是我第一次在博客里展示学习中国作者的教材的笔记。我选择这本书的依据是作者同时…

input输入框的23中类型

HTML 的 <input> 元素支持多种类型&#xff0c;这些类型决定了用户如何与表单控件进行交互。以下是 HTML5 中 <input> 元素的 23 种类型&#xff0c;以及每种类型的代码示例和效果图的描述&#xff08;请注意&#xff0c;由于文本的限制&#xff0c;我无法直接在这…

STM32day2

1.思维导图 个人暂时的学后感&#xff0c;不一定对&#xff0c;没什么东西&#xff0c;为做项目奔波中。。。1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。 while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */adc_val HAL_ADC_GetValue(&a…

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)

引言 其实C基础语法基本上已经学完&#xff0c;早就想开始写C的博客了&#xff0c;却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的&#xff0c;后来考虑了一下还是算了&#xff0c;等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…

JS函数

目录 1.Function声明 2.匿名函数 3.函数表达式 4.箭头函数 5.构造函数 个人版JS函数使用&#xff1a; 函数的声明&#xff1a;函数如果有return则返回的是 return 后面的值&#xff0c;如果函数没有有return 声明方式一&#xff1a; 声明方式二&#xff1a;变量名声明…

Java ElasticSearch面试题

Java ES-ElasticSearch面试题 前言1、ElasticSearch是什么&#xff1f;2. 说说你们公司ES的集群架构&#xff0c;索引数据大小&#xff0c;分片有多少 &#xff1f;3. ES的倒排索引是什么&#xff1f;4. ES是如何实现 master 选举的?5. 描述一下 ES索引文档的过程&#xff1a;…

STM32CubeMX学习笔记15---CAN总线

1、CAN简介 CAN总线网络的结构有闭环和开环两种形式 闭环结构的CAN总线网络&#xff0c;总线两端各连接一个1202的电阻。这种CAN总线网络由ISO11898标准定义&#xff0c;是高速、短距离的CAN网络&#xff0c;通信速率为125kbit/s到1Mbit/s。在1Mbit/s通信速率时&#x…

基于springboot的作业管理系统论文

摘 要 使用旧方法对作业管理信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在作业管理信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的作业管理系统有…

记录一次自己的服务器迁移过程

记录一次自己的服务器迁移过程 记录一次自己的服务器迁移过程 前言目前项目的部署方式开始迁移 提前准备设置安全组开始初始化安装 docker尝试部署数据库迁移 结尾一些问题 为什么中间没有配置 https?关于数据库备份 前言 最近阿里云发动了史上最大力度价格战&#xff0c…

Git小册-笔记迁移

Git简介 Git是目前世界上最先进的分布式版本控制系统&#xff08;没有之一&#xff09;。 所有的版本控制系统&#xff0c;其实只能跟踪文本文件的改动&#xff0c;比如TXT文件&#xff0c;网页&#xff0c;所有的程序代码等等&#xff0c;Git也不例外。版本控制系统可以告诉…

GB 2312字符集:中文编码的基石

title: GB 2312字符集&#xff1a;中文编码的基石 date: 2024/3/7 19:26:00 updated: 2024/3/7 19:26:00 tags: GB2312编码中文字符集双字节编码区位码规则兼容性问题存储空间优化文档处理应用 一、GB 2312字符集的背景 GB 2312字符集是中国国家标准委员会于1980年发布的一种…

【JavaEE初阶 -- 计算机核心工作机制】

这里写目录标题 1.冯诺依曼体系2.CPU是怎么构成的3.指令表4.CPU执行代码的方式5.CPU小结&#xff1a;6.编程语言和操作系统7. 进程/任务&#xff08;Process/Task&#xff09;8.进程在系统中是如何管理的9. CPU分配 -- 进程调度10.内存分配 -- 内存管理11.进程间通信 1.冯诺依曼…

SpringBoot【问题 05】PostgreSQL数据库启用SSL后使用默认配置进行数据库连接(Navicat工具与Java程序)

官网SSL说明&#xff1a;https://www.postgresql.org/docs/9.1/libpq-ssl.html 1.配置 1.1 文件 使用SSL需要的4个文件&#xff0c;名称要一致&#xff1a; 客户端密钥&#xff1a;postgresql.keyJava客户端密钥&#xff1a;postgresql.pk8客户端证书&#xff1a;postgresq…

计算机网络:应用层知识点汇总

文章目录 一、网络应用模型二、域名系统&#xff08;DNS&#xff09;三、文本传输协议&#xff08;FTP&#xff09;四、电子邮件五、万维网和HTTP协议 一、网络应用模型 p2p也就是对等模型 二、域名系统&#xff08;DNS&#xff09; 我们知道&#xff0c;随着人们建立一个网站…

【软件测试】上岗第一天,组长就要我做自动化测试?我该咋办?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 如果你恰好刚刚进…

探讨倒排索引Elasticsearch面试与实战:从理论到实践

在当前大数据时代&#xff0c;Elasticsearch&#xff08;以下简称为ES&#xff09;作为一种强大的搜索和分析引擎&#xff0c;受到了越来越多企业的青睐。因此&#xff0c;对于工程师来说&#xff0c;掌握ES的面试准备和实战经验成为了必备技能之一。本文将从ES的面试准备和实际…

玩转安卓之配置gradle-8.2.1

概述&#xff1a;看了一下&#xff0c;由于gradle是国外的&#xff0c;所以下载速度很慢&#xff0c;这个老师又是很菜的类型&#xff0c;同学又不会&#xff0c;于是曹某就写这一篇文章&#xff0c;教大家学会简单的为安卓配置gradle-8.2.1。 第一步&#xff1a;下载gradle-8…

高级控件

1.下拉列表 package com.tiger.chapter08;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner;public class Spi…

Vue2+3

vue相关介绍 Vue的两种使用方式&#xff1a; 1、vue核心包开发 场景&#xff1a;局部模块改造 2、vue核心包&vue插件工程化开发 场景&#xff1a;整站开发 概念&#xff1a;vue是用于构建用户界面的渐进式框架 创建vue实例 创建Vue实例&#xff0c;初始化渲染步骤&am…