当前位置: 首页 > news >正文

vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略

目录

引言

一、设计

1. 树状图(不方便呈现节点之间的关系,次要考虑)

2. 力引导依赖关系图

二、力引导关系图

三、如何实现节点的Open Or Fold

1. 设计逻辑

节点展开细节

节点收缩细节

代码实现

四、结果呈现

五、完整代码


引言

我考虑到如何实现关系图的缩放,但是关系图并不是简单的一个树结构,关系会存在于各个节点之间,两个同一层级之间的节点之间也会有一定的关系。

那么如何实现节点之间的折叠和展开策略,成为了这个图设计的关键要素。

一、设计

1. 树状图(不方便呈现节点之间的关系,次要考虑)

2. 力引导依赖关系图

    引力中心为图片中心(考虑到尽可能多的呈现信息,所以引力中心设置为中心)

    层级设计:重量按照由中心向四周分布,层级权重也是如此分布。

二、力引导关系图

"力引导关系图"通常指的是一种可视化方法,用于展示图形中节点之间的关系和连接。这种图形通常采用力导向布局算法,其中节点之间的吸引力和排斥力被用来模拟真实世界中的物理力,以确定节点在图中的相对位置。

  1. 节点(Nodes): 表示图中的个体、对象或数据点。每个节点通常代表一个实体,如人物、城市、概念等。

  2. 边(Edges): 表示节点之间的连接或关系。边可以是有向的或无向的,具体取决于关系的性质。

  3. 力导向布局算法: 使用物理模型来模拟节点之间的力的作用,以确定节点的位置。这些力包括吸引力(使相连接的节点靠近)和排斥力(使不相连接的节点远离)。这种算法通过模拟物理系统中的粒子之间的相互作用来达到节点布局的目的。

  4. 布局: 节点根据力导向算法的计算结果被放置在图形中的特定位置,以便更好地展示节点之间的关系。

  5. 可视化: 力引导关系图提供了一种直观的方式来理解图中节点的关系,使得那些有关联的节点更接近,而没有关联的节点相对较远。这有助于发现图中的模式、集群或其他重要信息。

这种图形在许多领域中都有应用,例如社交网络分析、生物信息学、知识图谱可视化等。

三、如何实现节点的Open Or Fold

echarts3之后的关系图节点的书写按照以下规则:

var myChart = echarts.init(document.getElementById('main'), 'macarons');            // 指定图表的配置项和数据var option = {tooltip : {show : true,   //默认显示showContent:true, //是否显示提示框浮层trigger:'item',//触发类型,默认数据项触发triggerOn:'click',//提示触发条件,mousemove鼠标移至触发,还有click点击触发alwaysShowContent:false, //默认离开提示框区域隐藏,true为一直显示showDelay:0,//浮层显示的延迟,单位为 ms,默认没有延迟,也不建议设置。在 triggerOn 为 'mousemove' 时有效。hideDelay:200,//浮层隐藏的延迟,单位为 ms,在 alwaysShowContent 为 true 的时候无效。enterable:false,//鼠标是否可进入提示框浮层中,默认为false,如需详情内交互,如添加链接,按钮,可设置为 true。position:'right',//提示框浮层的位置,默认不设置时位置会跟随鼠标的位置。只在 trigger 为'item'的时候有效。confine:false,//是否将 tooltip 框限制在图表的区域内。外层的 dom 被设置为 'overflow: hidden',或者移动端窄屏,导致 tooltip 超出外界被截断时,此配置比较有用。transitionDuration:0.4,//提示框浮层的移动动画过渡时间,单位是 s,设置为 0 的时候会紧跟着鼠标移动。formatter: function (params, ticket, callback) {//判断数据,提供相应的url。var path="";var node=params.data; //当前选中节点数据var category=params.data.category;  //选中节点图例0负载 1中间件 2端口号 3数据库 4用户名 if(category==2){ //为jvm 虚拟机各类参数的路径path = "${ctx}/weblogic.do?host=" + node.host + "&port="+ node.port + "&username=" + node.username+ "&pwd=" + node.pwd; //准备访问路径}else if(category==4){ //为jdbc 数据库的路径path = "${ctx}/oracle.do?host=" + node.host + "&port="+ node.port + "&username=" + node.username+ "&pwd=" + node.pwd + "&instance="+ node.instance; //准备访问路径}console.log(params);$.ajax({async : true,//设置异、同步加载cache : false,//false就不会从浏览器缓存中加载请求信息了type : 'post',dataType : "json",url : path,//请求的action路径  success : function(data) { //请求成功后处理函数。    //加工返回后的数据debugger;if(category==2){ //当选择端口号时var res = 'jvm最大内存值:' + data.memoryMaxSize+'<br/>';res+='jvm空闲内存值:'+data.memoryFreeSize+'<br/>';res+='jvm内存使用率:'+data.memoryPer+'<br/>';res+='空闲线程:'+data.ideThread+'<br/>';res+='总线程:'+data.totalThread+'<br/>';res+='每秒处理的线程数比率:'+data.throuhput+'<br/>';callback(ticket,res);}else if(category==4){//当选择用户名时var res = '当前链接数:'+data.processCount+'<br/>';res+='最大链接数:'+data.maxProcessCount+'<br/>';callback(ticket,res);}},error : function() {//请求失败处理函数  $.messager.alert('警告', '请求失败!', 'warning');}});if(category==2||category==4){ //当选择端口号与用户名时提示加载return "loading";}else{                   //其他情况显示所属图例以及名称return myChart.getOption().series[params.seriesIndex].categories[params.data.category].name+":"+params.name;}}},legend : { //=========圖表控件show : true,data : [ {name : '负载',icon : 'rect'//'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'},{name : '中间件',icon : 'roundRect'}, {name : '端口号',icon : 'circle'}, {name : '数据库',icon : 'circle'},{name : '用户名',icon : 'roundRect'} ]},series : [ {type : 'graph', //关系图name : "监控管理系统", //系列名称,用于tooltip的显示,legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。layout : 'force', //图的布局,类型为力导图,'circular' 采用环形布局,见示例 Les MiserableslegendHoverLink : true,//是否启用图例 hover(悬停) 时的联动高亮。hoverAnimation : true,//是否开启鼠标悬停节点的显示动画coordinateSystem : null,//坐标系可选xAxisIndex : 0, //x轴坐标 有多种坐标系轴坐标选项yAxisIndex : 0, //y轴坐标 force : { //力引导图基本配置//initLayout: ,//力引导的初始化布局,默认使用xy轴的标点repulsion : 100,//节点之间的斥力因子。支持数组表达斥力范围,值越大斥力越大。gravity : 0.03,//节点受到的向中心的引力因子。该值越大节点越往中心点靠拢。edgeLength :80,//边的两个节点之间的距离,这个距离也会受 repulsion。[10, 50] 。值越小则长度越长layoutAnimation : true//因为力引导布局会在多次迭代后才会稳定,这个参数决定是否显示布局的迭代动画,在浏览器端节点数据较多(>100)的时候不建议关闭,布局过程会造成浏览器假死。                        },roam : true,//是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启nodeScaleRatio : 0.6,//鼠标漫游缩放时节点的相应缩放比例,当设为0时节点不随着鼠标的缩放而缩放draggable : true,//节点是否可拖拽,只在使用力引导布局的时候有用。focusNodeAdjacency : true,//是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。//symbol:'roundRect',//关系图节点标记的图形。ECharts 提供的标记类型包括 'circle'(圆形), 'rect'(矩形), 'roundRect'(圆角矩形), 'triangle'(三角形), 'diamond'(菱形), 'pin'(大头针), 'arrow'(箭头)  也可以通过 'image://url' 设置为图片,其中 url 为图片的链接。'path:// 这种方式可以任意改变颜色并且抗锯齿//symbolSize:10 ,//也可以用数组分开表示宽和高,例如 [20, 10] 如果需要每个数据的图形大小不一样,可以设置为如下格式的回调函数:(value: Array|number, params: Object) => number|Array//symbolRotate:,//关系图节点标记的旋转角度。注意在 markLine 中当 symbol 为 'arrow' 时会忽略 symbolRotate 强制设置为切线的角度。//symbolOffset:[0,0],//关系图节点标记相对于原本位置的偏移。[0, '50%']edgeSymbol : [ 'none', 'none' ],//边两端的标记类型,可以是一个数组分别指定两端,也可以是单个统一指定。默认不显示标记,常见的可以设置为箭头,如下:edgeSymbol: ['circle', 'arrow']edgeSymbolSize : 10,//边两端的标记大小,可以是一个数组分别指定两端,也可以是单个统一指定。itemStyle : {//===============图形样式,有 normal 和 emphasis 两个状态。normal 是图形在默认状态下的样式;emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。normal : { //默认样式label : {show : true},borderType : 'solid', //图形描边类型,默认为实线,支持 'solid'(实线), 'dashed'(虚线), 'dotted'(点线)。borderColor : 'rgba(255,215,0,0.4)', //设置图形边框为淡金色,透明度为0.4borderWidth : 2, //图形的描边线宽。为 0 时无描边。opacity : 1// 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。默认0.5},emphasis : {//高亮状态}},lineStyle : { //==========关系边的公用线条样式。normal : {color : 'rgba(255,0,255,0.4)',width : '3',type : 'dotted', //线的类型 'solid'(实线)'dashed'(虚线)'dotted'(点线)curveness : 0.3, //线条的曲线程度,从0到1opacity : 1// 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。默认0.5},emphasis : {//高亮状态}},label : { //=============图形上的文本标签normal : {show : true,//是否显示标签。position : 'inside',//标签的位置。['50%', '50%'] [x,y]textStyle : { //标签的字体样式color : '#cde6c7', //字体颜色fontStyle : 'normal',//文字字体的风格 'normal'标准 'italic'斜体 'oblique' 倾斜fontWeight : 'bolder',//'normal'标准'bold'粗的'bolder'更粗的'lighter'更细的或100 | 200 | 300 | 400...fontFamily : 'sans-serif', //文字的字体系列fontSize : 12, //字体大小}},emphasis : {//高亮状态}},edgeLabel : {//==============线条的边缘标签 normal : {show : false},emphasis : {//高亮状态}},//别名为nodes   name:影响图形标签显示,value:影响选中后值得显示,category:所在类目的index,symbol:类目节点标记图形,symbolSize:10图形大小//label:标签样式。data : [ {id : 0,category : 0,name : '101.133.8.88',symbol : 'roundRect',value : 20,symbolSize : 80}, {id : 1,category : 1,name : '192.168.8.88',symbol : 'rect',value : 20,symbolSize : 70}, {id : 2,category : 2,name : '7001',symbol : 'circle',value : 20,symbolSize : 60,yId:"jvm",host:"192.168.6.37",port:"7001",username:"weblogic",pwd:"weblogic1"}, {id : 3,category : 2,name : '7100',symbol : 'circle',value : 20,symbolSize : 60}, {id : 4,category : 1,name : '102.12.33.23',symbol : 'rect',value : 20,symbolSize : 70}, {id : 5,category : 2,name : '7001',symbol : 'circle',value : 20,symbolSize : 60}, {id : 6,category : 2,name : '7100',symbol : 'circle',value : 20,symbolSize : 60}, {id : 7,category : 2,name : '7001',symbol : 'circle',value : 20,symbolSize : 60}, {id : 8,category : 1,name : '101.11.66.6',symbol : 'rect',value : 20,symbolSize : 70}, {id : 9,category : 2,name : '7101',symbol : 'circle',value : 20,symbolSize : 60}, {id : 10,category : 2,name : '7101',symbol : 'circle',value : 20,symbolSize : 60}, {id : 11,category : 2,name : '7001',symbol : 'circle',value : 20,symbolSize : 60}, {id : 12,category : 2,name : '7100',symbol : 'circle',value : 20,symbolSize : 60}, {id : 13,category : 3,name : '192.168.44.44',symbol : 'circle',value : 20,symbolSize : 70}, {id : 14,category : 3,name : '192.168.33.33',symbol : 'circle',value : 20,symbolSize : 70}, {id : 15,category : 3,name : '192.168.22.22',symbol : 'circle',value : 20,symbolSize : 70}, {id : 16,category : 4,name : '55555555555',symbol : 'circle',value : 20,symbolSize : 70,yId:"jdbc",port:"1521",host:"192.168.11.11",username:"222222222",pwd:"11111111",instance:"orcl"}],categories : [ //symbol name:用于和 legend 对应以及格式化 tooltip 的内容。 label有效{name : '负载',symbol : 'rect',label : { //标签样式}}, {name : '中间件',symbol : 'rect'}, {name : '端口号',symbol : 'roundRect'}, {name : '数据库',symbol : 'roundRect'}, {name : '用户名',symbol : 'roundRect'} ],links : [ //edges是其别名代表节点间的关系数据。{source : 1,target : 0}, {source : 4,target : 0}, {source : 8,target : 0}, {source : 2,target : 1}, {source : 3,target : 1}, {source : 5,target : 4}, {source : 6,target : 4}, {source : 7,target : 4}, {source : 9,target : 8}, {source : 10,target : 8}, {source : 11,target : 8}, {source : 12,target : 8}, {source : 13,target : 6}, {source : 14,target : 6}, {source : 15,target : 2}, {source : 16,target : 15} ]} ]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);/*ECharts3 方法部分 开始*/function openOrFold(params) {  //该事件会提示节点间关系...}//var ecConfig = echarts.config; echarts2的获取事件方法,当前为echarts3myChart.on('mouseover', openOrFold);//'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'、'mouseover'、'mouseout' /*ECharts3 方法部分 结束*//*ECharts3 结束*/

那么如何实现鼠标点击或者悬停实现节点的折叠和展开呢?

1. 设计逻辑

节点展开细节

需求逐级展开,每次展开节点周围一层的节点,并且绘制出已存在节点的关系。

节点收缩细节

需求逐层收缩,每次收缩周围一层的节点,并且取消消失节点之间的关系。

为了保持思维流畅性(用户友好性),在收缩的时候采取,收缩当前节点的子节点,并且收缩上一层节点的孤立点,下一层的并不实现收缩。

代码实现

openOrFold(param) {var option = this.myChart1.getOption();var nodesOption = option.series[0].data;var linksOption = option.series[0].edges;var data = param.data;var linksNodes = [];if (data != null && data != undefined) {if (data.flag) {var tempNodes = [];// 如果节点已经展开,将其所有的关联节点隐藏for (let m in linksOption) {// 找上下“已经显示的孤立的”层节点隐藏if (linksOption[m].target == data.id &&nodesOption[linksOption[m].source].category >= 0 &&!nodesOption[linksOption[m].source].flag) {// 找下层// tempNodes.push(nodesOption[linksOption[m].source])linksNodes.push(linksOption[m].source);} else if (linksOption[m].source == data.id &&nodesOption[linksOption[m].target].category >= 0 &&!nodesOption[linksOption[m].target].flag) {// 找上层tempNodes.push(nodesOption[linksOption[m].target])linksNodes.push(linksOption[m].target);}}// 找孤立点var temp = [];for(let i in linksOption){for(let j in tempNodes){if(linksOption[i].target == tempNodes[j].id&& nodesOption[linksOption[i].source].category>=0 && linksOption[i].source != data.id){// console.log(linksOption[i])temp.push(linksOption[i].target)}else if(linksOption[i].source == tempNodes[j].id&& nodesOption[linksOption[i].target].category>=0 && linksOption[i].target != data.id){temp.push(linksOption[i].source)}}}var  uniqueTemp = [...new Set(temp)]var elementsSet = new Set(uniqueTemp)linksNodes = linksNodes.filter(item=>!elementsSet.has(item))// 将上下层节点的隐藏设置if (linksNodes != null && linksNodes != undefined) {for (let k in linksNodes) {nodesOption[linksNodes[k]].category =nodesOption[linksNodes[k]].category * -1;}nodesOption[data.id].flag = false;}} else {// 如果节点未展开,将其所有的关联节点打开for (let m in linksOption) {// 找上下“未显示的”层节点if (linksOption[m].target == data.id &&nodesOption[linksOption[m].source].category < 0) {// 找下层linksNodes.push(linksOption[m].source);} else if (linksOption[m].source == data.id &&nodesOption[linksOption[m].target].category < 0) {// 找上层linksNodes.push(linksOption[m].target);}}// 将上下层节点的显示设置if (linksNodes != null && linksNodes != undefined) {for (let k in linksNodes) {nodesOption[linksNodes[k]].category =nodesOption[linksNodes[k]].category * -1;}nodesOption[data.id].flag = true;}}// option.series[0].data = linksNodes;this.myChart1.setOption(option);}},

按照这个逻辑则可以画出如下所示视频中的节点折叠和展开。

四、结果呈现

FlodOrOPen

五、完整代码

一页完整的vue代码,DemoView.vue

数据来源:https://echarts.apache.org/examples/data/asset/data/webkit-dep.json

<template><div class="connection"><div id="chart1" style="width: 90vw; height: 90vh"></div></div>
</template><script>
export default {data() {return {myChart1: null,webkitDep: {}};},methods: {init() {var webkitDep = this.webkitDep;this.myChart1 = this.$echarts.init(document.getElementById("chart1"));var option = {legend: {data: ["Spine", "Switch", "Node"],},tooltip:{formatter: (params) =>{var chartData = params.data;if(params.dataType == "node"){var htmlContent = `<div style='min-width: 310px;background: #fff; padding: 10px 5px;color: #999;font-weight: 900;'><div style='font-size: 14px;margin-bottom: 10px;'>${"基本信息"}</div><div style='font-size: 12px;line-height: 24px;'><div style="width: 100%;"><span style='display: inline-block;width: 80px;text-align: right;padding-right: 10px;'>${"名称:"}</span><span style='display: inline-block;width: 180px;color: #000;'>${chartData.name}</span></div><div style="width: 100%;"><span style='display: inline-block;width: 80px;text-align: right;padding-right: 10px;'>${"状态:"}</span><span style='display: inline-block;width: 10px;height: 10px;text-align: center;background: red;border-radius: 50%;'></span><span style='display: inline-block;width: 180px;color: #000;'>${chartData.state}</span></div><div style="width: 100%;"><span style='display: inline-block;width: 80px;text-align: right;padding-right: 10px;'>${"IP地址:"}</span><span style='display: inline-block;width: 180px;color: #000;'>${chartData.ip}</span></div></div><div class="btn-tooltip" style='width: 100%; text-align: right;padding-right: 10px;color: #1e9fff; cursor: pointer;' onclick="chartClick">详情>></div></div>`}else if(params.dataType == "edge"){}return htmlContent}},series: [{type: "graph",layout: "force",animation: false,label: {show: false ,position: "right",formatter: "{b}",},draggable: true,roam: true,data: webkitDep.nodes.map(function (node, idx) {node.id = idx;return node;}),categories: webkitDep.categories,force: {// edgeLength: [50,100],repulsion: 500,gravity: 0,},edges: webkitDep.links,emphasis: {focus: "adjacency",label: {position: "right",show: true,},},},],};this.myChart1.setOption(option);this.myChart1.on("click", this.openOrFold);},openOrFold(param) {var option = this.myChart1.getOption();var nodesOption = option.series[0].data;var linksOption = option.series[0].edges;var data = param.data;var linksNodes = [];if (data != null && data != undefined) {if (data.flag) {var tempNodes = [];// 如果节点已经展开,将其所有的关联节点隐藏for (let m in linksOption) {// 找上下“已经显示的孤立的”层节点隐藏if (linksOption[m].target == data.id &&nodesOption[linksOption[m].source].category >= 0 &&!nodesOption[linksOption[m].source].flag) {// 找下层// tempNodes.push(nodesOption[linksOption[m].source])linksNodes.push(linksOption[m].source);} else if (linksOption[m].source == data.id &&nodesOption[linksOption[m].target].category >= 0 &&!nodesOption[linksOption[m].target].flag) {// 找上层tempNodes.push(nodesOption[linksOption[m].target])linksNodes.push(linksOption[m].target);}}// 找孤立点var temp = [];for(let i in linksOption){for(let j in tempNodes){if(linksOption[i].target == tempNodes[j].id&& nodesOption[linksOption[i].source].category>=0 && linksOption[i].source != data.id){// console.log(linksOption[i])temp.push(linksOption[i].target)}else if(linksOption[i].source == tempNodes[j].id&& nodesOption[linksOption[i].target].category>=0 && linksOption[i].target != data.id){temp.push(linksOption[i].source)}}}var  uniqueTemp = [...new Set(temp)]var elementsSet = new Set(uniqueTemp)linksNodes = linksNodes.filter(item=>!elementsSet.has(item))// 将上下层节点的隐藏设置if (linksNodes != null && linksNodes != undefined) {for (let k in linksNodes) {nodesOption[linksNodes[k]].category =nodesOption[linksNodes[k]].category * -1;}nodesOption[data.id].flag = false;}} else {// 如果节点未展开,将其所有的关联节点打开for (let m in linksOption) {// 找上下“未显示的”层节点if (linksOption[m].target == data.id &&nodesOption[linksOption[m].source].category < 0) {// 找下层linksNodes.push(linksOption[m].source);} else if (linksOption[m].source == data.id &&nodesOption[linksOption[m].target].category < 0) {// 找上层linksNodes.push(linksOption[m].target);}}// 将上下层节点的显示设置if (linksNodes != null && linksNodes != undefined) {for (let k in linksNodes) {nodesOption[linksNodes[k]].category =nodesOption[linksNodes[k]].category * -1;}nodesOption[data.id].flag = true;}}// option.series[0].data = linksNodes;this.myChart1.setOption(option);}},},mounted() {this.init();},
};
</script><style scoped></style>

相关文章:

vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略

目录 引言 一、设计 1. 树状图&#xff08;不方便呈现节点之间的关系&#xff0c;次要考虑&#xff09; 2. 力引导依赖关系图 二、力引导关系图 三、如何实现节点的Open Or Fold 1. 设计逻辑 节点展开细节 节点收缩细节 代码实现 四、结果呈现 五、完整代码 引言 我…...

Unity3d 灯光阴影开启,法线贴图出现BUG

URP项目打开灯光的阴影后&#xff0c;法线贴图出现BUG 解决方案&#xff1a;按照下图所示调整材质的选项即可...

c语言:模拟实现atoi函数

atoi函数的功能和用法&#xff1a; 主要功能&#xff1a;将字符串转换为整数。例如&#xff0c;将字符类型的“123”转换为整数123. #include <stdio.h> #include <stdlib.h>int main() {char str[] "123";int num atoi(str);printf("Converted …...

Docker 使用心得

创建一个docker 镜像&#xff0c;相关运行代码&#xff0c;放在docker镜像文件同级&#xff0c; pm2 不能与 docker一起使用&#xff08;&#xff09; # node 服务docker FROM node:10.16.3LABEL author"sj"RUN mkdir -p /var/nodeCOPY ./node /var/nodeWORKDIR /va…...

Nacos 架构原理

基本架构及概念​ 服务 (Service)​ 服务是指一个或一组软件功能&#xff08;例如特定信息的检索或一组操作的执行&#xff09;&#xff0c;其目的是不同的客户端可以为不同的目的重用&#xff08;例如通过跨进程的网络调用&#xff09;。Nacos 支持主流的服务生态&#xff0c…...

尝试修改vim光标的思路

尝试修改vim光标&#xff0c;失败 想让vim的光标在不同模式下显示不同样式 尝试了很多方法&#xff0c;但是没有作用 " Set cursor shape and color if &term ~ "xterm"" INSERT modelet &t_SI "\<Esc>[6 q" . "\<Esc&…...

SpringBoot整合Activiti7——消息事件(十)

文章目录 消息事件开始事件中间事件边界事件代码实现xml文件测试流程流程执行步骤 消息事件 消息事件只有一个接收者&#xff0c;消息具有名字与载荷。 信息会储存在 act_ru_event_subscr 表中。 <!-- 定义消息 --> <message id"msgId1" name"msgName…...

高翔:《自动驾驶与机器人中的SLAM技术 》-Slam_in_autonomous_driving 编译过程中遇到的问题

使用的环境是ubuntu20.04 问题1.安装g2o没有问题&#xff0c;不过在编译整个项目工程时候报错&#xff1a; ”openmp_mutex.h: 30:10: fatal error: g2o/config.h: No such file or directory“: 解决办法&#xff1a; 只需要将/thirdparty/g2o/build/g2o下的config.h放到/…...

org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 实现密码加密 验证 代码示例

BCryptPasswordEncoder 是 Spring Security 提供的用于加密和验证密码的实现类。它使用强大的 BCrypt 散列函数来存储密码的散列值&#xff0c;提供了一种安全的密码存储方法。以下是一个简单的示例代码&#xff0c;演示如何使用 BCryptPasswordEncoder 进行密码加密和验证&…...

《微信小程序开发从入门到实战》学习三十八

4.2 云开发JSON数据库 4.2.9 条件查询与查询指令 在查询数据时&#xff0c;有时需要对查找的数据添加一些限定条件&#xff0c;只获取满足给定条件的数据&#xff0c;这样的查询称为条件查询。 可以在集合引用上使用where方法指定查询条件&#xff0c;再用get方法&#xff0…...

云服务器哪家便宜?亚马逊AWS等免费云服务器推荐

在这数字化的时代&#xff0c;云计算技术越来越广泛应用于各种场景&#xff0c;尤其是云服务器&#xff0c;作为一种全新的服务器架构正在逐渐取代传统的物理服务器&#xff0c;“云服务器哪家便宜”等用户相关问题也受到越来越多的关注。自从亚马逊最早推出了首个云计算服务—…...

Linux删除了大文件为什么磁盘空间没有释放?

某天&#xff0c;收到监控系统的告警信息&#xff0c;说磁盘空间占用过高&#xff0c;登上服务器&#xff0c;使用 df -h 一看&#xff0c;发现磁盘占用率已经 96%了&#xff1a; 通过查看 /usr/local/nginx/conf/vhost/xxx.conf 找到 access_log 和 error_log 的路径&#x…...

编写bat脚本执行msyql建库sql

使用cmd命令执行(windows下) 【MySQL的bin目录】\mysql –u用户名 –p密码 –D数据库<【sql脚本文件路径全名】&#xff0c;示例&#xff1a; D:\mysql\bin\mysql –uroot –p123456 -Dtest<d:\test\ss.sql 注意&#xff1a; A、如果在sql脚本文件中使用了use 数据库&…...

【JavaSE学习专栏】第04篇 Java面向对象

文章目录 1 面向过程&面向对象2 类和对象2.1 对象的特征2.2 java类及类的成员2.3 类的语法格式 3 创建与初始化对象3.1 类的成员之一&#xff1a;属性3.2 类的成员之二&#xff1a;方法3.3 类的成员之三&#xff1a;构造器&#xff08;构造方法&#xff09;3.3.1 无参构造方…...

sCrypt 在英国伦敦 Exeter 大学讲学

6月5日&#xff0c;sCrypt CEO晓晖和他的两位同事在英国伦敦Exeter大学举行了一场精彩的讲座。刘晓晖向听众们详细介绍了sCrypt智能合约开平台&#xff0c;并演示了如何使用sCrypt来开发基于比特币的智能合约。他用生动形象的语言&#xff0c;深入浅出地解释了这个领域复杂而又…...

人工智能基础创新的第二增长曲线

编者按&#xff1a;2023年是微软亚洲研究院建院25周年。借此机会&#xff0c;我们特别策划了“智启未来”系列文章&#xff0c;邀请到微软亚洲研究院不同研究领域的领军人物&#xff0c;以署名文章的形式分享他们对人工智能、计算机及其交叉学科领域的观点洞察及前沿展望。希望…...

华为OD机试真题-分割均衡字符串-2023年OD统一考试(C卷)

题目描述&#xff1a; 均衡串定义&#xff1a;字符串只包含两种字符&#xff0c;且两种字符的个数相同。 给定一个均衡字符串&#xff0c;请给出可分割成新的均衡子串的最大个数。 约定字符串中只包含大写的X和Y两种字符。 输入描述&#xff1a; 均衡串&#xff1a;XXYYXY 字符…...

基于SpringBoot的图书推荐系统的

摘 要 网络信息技术的高速发展&#xff0c;使得高校图书馆的服务空间日益扩大&#xff0c;依据个人特点的针对性服务逐渐成为新服务模式的主导趋势。对于大多数用户而言&#xff0c;很难在大量的学术图书馆中快速找到他们想要的材料。另外&#xff0c;随着时代的不断发展&…...

02_学习使用javax_ws_rs_下载文件

文章目录 1 前言2 Maven 依赖3 下载接口4 如何返回文件&#xff1f;5 感谢 1 前言 专栏上一篇&#xff0c;写了如何使用 javax.ws.rs 上传文件&#xff0c;那么必然的&#xff0c;我们得再学习学习如何下载文件&#x1f600; 2 Maven 依赖 这个就不赘述了&#xff0c;和上一篇…...

js校验多个时间段的时间是否有交叉

参考博客&#xff1a; Java日期时间API系列37-----时间段是否有重叠&#xff08;交集&#xff09;的计算方法 Java 最优雅方式校验时间段重叠 判断是否有交叉数据 let timePeriod [{start: dateList[0].value, //时间段1的开始时间 时间格式为1130&#xff08;代表11&#xf…...

Python Spyder开发的应用项目

Python是一种功能强大且受欢迎的编程语言&#xff0c;被广泛应用于科学计算、数据分析和机器学习等领域。而Spyder则是一款专为科学计算和数据分析而设计的Python集成开发环境&#xff08;IDE&#xff09;。本文将介绍Spyder的特点、功能以及如何使用。 特点 Spyder具有以下主…...

ES6知识点

ES6 知识点及常考面试题 var、let 及 const 区别 涉及面试题&#xff1a;什么是提升&#xff1f;什么是暂时性死区&#xff1f;var、let 及 const 区别&#xff1f;对于这个问题&#xff0c;我们应该先来了解提升&#xff08;hoisting&#xff09;这个概念。 console.log(a)…...

数据结构详解各种算法

1、设有两个整型顺序表L1&#xff0c;L2&#xff0c;其元素值递增有序存放&#xff0c;请定义该顺序表的元素类型及表类型,设计以下自定义函数&#xff1a; &#xff08;1&#xff09;录入顺序表中所有元素的值。 &#xff08;2&#xff09;将顺序表L1&#xff0c;L2合并为到…...

Qt实现右键菜单

一、实现方法 QWidget提供了虚函数: virtual void contextMenuEvent(QContextMenuEvent*event);覆写该函数&#xff0c;即可。 二、Example 创建一个基本的mainwindow项目&#xff0c; 头文件&#xff1a; class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWin…...

MySQL基础篇一

基础篇 通用语法及分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09; DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改 DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录 DCL: 数据控制语言&#xff…...

深入了解Java8新特性-日期时间API:OffsetDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概24000多字&#xff0c;预计阅读时间长需要20分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…...

企业微信http协议接口开发,发送位置消息

产品说明 一、 hook版本&#xff1a;企业微信hook接口是指将企业微信的功能封装成dll&#xff0c;并提供简易的接口给程序调用。通过hook技术&#xff0c;可以在不修改企业微信客户端源代码的情况下&#xff0c;实现对企业微信客户端的功能进行扩展和定制化。企业微信hook接口…...

CSS——基础选择器、文字控制属性

1、CSS定义 层叠样式表&#xff08;Cascading Style Sheets&#xff0c;缩写为CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09;。 书写位置&#xff1a;title 标签下方添加style双标签&#xff0c;styl…...

08-中介者模式-C语言实现

中介者模式&#xff1a; Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.&#xff08;用一个中介对…...

【开源】基于JAVA的医院门诊预约挂号系统

项目编号&#xff1a; S 033 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S033&#xff0c;文末获取源码。} 项目编号&#xff1a;S033&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2…...