vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略
目录
引言
一、设计
1. 树状图(不方便呈现节点之间的关系,次要考虑)
2. 力引导依赖关系图
二、力引导关系图
三、如何实现节点的Open Or Fold
1. 设计逻辑
节点展开细节
节点收缩细节
代码实现
四、结果呈现
五、完整代码
引言
我考虑到如何实现关系图的缩放,但是关系图并不是简单的一个树结构,关系会存在于各个节点之间,两个同一层级之间的节点之间也会有一定的关系。
那么如何实现节点之间的折叠和展开策略,成为了这个图设计的关键要素。
一、设计
1. 树状图(不方便呈现节点之间的关系,次要考虑)
2. 力引导依赖关系图
引力中心为图片中心(考虑到尽可能多的呈现信息,所以引力中心设置为中心)
层级设计:重量按照由中心向四周分布,层级权重也是如此分布。
二、力引导关系图
"力引导关系图"通常指的是一种可视化方法,用于展示图形中节点之间的关系和连接。这种图形通常采用力导向布局算法,其中节点之间的吸引力和排斥力被用来模拟真实世界中的物理力,以确定节点在图中的相对位置。
-
节点(Nodes): 表示图中的个体、对象或数据点。每个节点通常代表一个实体,如人物、城市、概念等。
-
边(Edges): 表示节点之间的连接或关系。边可以是有向的或无向的,具体取决于关系的性质。
-
力导向布局算法: 使用物理模型来模拟节点之间的力的作用,以确定节点的位置。这些力包括吸引力(使相连接的节点靠近)和排斥力(使不相连接的节点远离)。这种算法通过模拟物理系统中的粒子之间的相互作用来达到节点布局的目的。
-
布局: 节点根据力导向算法的计算结果被放置在图形中的特定位置,以便更好地展示节点之间的关系。
-
可视化: 力引导关系图提供了一种直观的方式来理解图中节点的关系,使得那些有关联的节点更接近,而没有关联的节点相对较远。这有助于发现图中的模式、集群或其他重要信息。
这种图形在许多领域中都有应用,例如社交网络分析、生物信息学、知识图谱可视化等。
三、如何实现节点的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. 树状图(不方便呈现节点之间的关系,次要考虑) 2. 力引导依赖关系图 二、力引导关系图 三、如何实现节点的Open Or Fold 1. 设计逻辑 节点展开细节 节点收缩细节 代码实现 四、结果呈现 五、完整代码 引言 我…...
Unity3d 灯光阴影开启,法线贴图出现BUG
URP项目打开灯光的阴影后,法线贴图出现BUG 解决方案:按照下图所示调整材质的选项即可...
c语言:模拟实现atoi函数
atoi函数的功能和用法: 主要功能:将字符串转换为整数。例如,将字符类型的“123”转换为整数123. #include <stdio.h> #include <stdlib.h>int main() {char str[] "123";int num atoi(str);printf("Converted …...
Docker 使用心得
创建一个docker 镜像,相关运行代码,放在docker镜像文件同级, pm2 不能与 docker一起使用() # node 服务docker FROM node:10.16.3LABEL author"sj"RUN mkdir -p /var/nodeCOPY ./node /var/nodeWORKDIR /va…...
Nacos 架构原理
基本架构及概念 服务 (Service) 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,…...
尝试修改vim光标的思路
尝试修改vim光标,失败 想让vim的光标在不同模式下显示不同样式 尝试了很多方法,但是没有作用 " Set cursor shape and color if &term ~ "xterm"" INSERT modelet &t_SI "\<Esc>[6 q" . "\<Esc&…...
SpringBoot整合Activiti7——消息事件(十)
文章目录 消息事件开始事件中间事件边界事件代码实现xml文件测试流程流程执行步骤 消息事件 消息事件只有一个接收者,消息具有名字与载荷。 信息会储存在 act_ru_event_subscr 表中。 <!-- 定义消息 --> <message id"msgId1" name"msgName…...
高翔:《自动驾驶与机器人中的SLAM技术 》-Slam_in_autonomous_driving 编译过程中遇到的问题
使用的环境是ubuntu20.04 问题1.安装g2o没有问题,不过在编译整个项目工程时候报错: ”openmp_mutex.h: 30:10: fatal error: g2o/config.h: No such file or directory“: 解决办法: 只需要将/thirdparty/g2o/build/g2o下的config.h放到/…...
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 实现密码加密 验证 代码示例
BCryptPasswordEncoder 是 Spring Security 提供的用于加密和验证密码的实现类。它使用强大的 BCrypt 散列函数来存储密码的散列值,提供了一种安全的密码存储方法。以下是一个简单的示例代码,演示如何使用 BCryptPasswordEncoder 进行密码加密和验证&…...
《微信小程序开发从入门到实战》学习三十八
4.2 云开发JSON数据库 4.2.9 条件查询与查询指令 在查询数据时,有时需要对查找的数据添加一些限定条件,只获取满足给定条件的数据,这样的查询称为条件查询。 可以在集合引用上使用where方法指定查询条件,再用get方法࿰…...
云服务器哪家便宜?亚马逊AWS等免费云服务器推荐
在这数字化的时代,云计算技术越来越广泛应用于各种场景,尤其是云服务器,作为一种全新的服务器架构正在逐渐取代传统的物理服务器,“云服务器哪家便宜”等用户相关问题也受到越来越多的关注。自从亚马逊最早推出了首个云计算服务—…...
Linux删除了大文件为什么磁盘空间没有释放?
某天,收到监控系统的告警信息,说磁盘空间占用过高,登上服务器,使用 df -h 一看,发现磁盘占用率已经 96%了: 通过查看 /usr/local/nginx/conf/vhost/xxx.conf 找到 access_log 和 error_log 的路径&#x…...
编写bat脚本执行msyql建库sql
使用cmd命令执行(windows下) 【MySQL的bin目录】\mysql –u用户名 –p密码 –D数据库<【sql脚本文件路径全名】,示例: D:\mysql\bin\mysql –uroot –p123456 -Dtest<d:\test\ss.sql 注意: A、如果在sql脚本文件中使用了use 数据库&…...
【JavaSE学习专栏】第04篇 Java面向对象
文章目录 1 面向过程&面向对象2 类和对象2.1 对象的特征2.2 java类及类的成员2.3 类的语法格式 3 创建与初始化对象3.1 类的成员之一:属性3.2 类的成员之二:方法3.3 类的成员之三:构造器(构造方法)3.3.1 无参构造方…...
sCrypt 在英国伦敦 Exeter 大学讲学
6月5日,sCrypt CEO晓晖和他的两位同事在英国伦敦Exeter大学举行了一场精彩的讲座。刘晓晖向听众们详细介绍了sCrypt智能合约开平台,并演示了如何使用sCrypt来开发基于比特币的智能合约。他用生动形象的语言,深入浅出地解释了这个领域复杂而又…...
人工智能基础创新的第二增长曲线
编者按:2023年是微软亚洲研究院建院25周年。借此机会,我们特别策划了“智启未来”系列文章,邀请到微软亚洲研究院不同研究领域的领军人物,以署名文章的形式分享他们对人工智能、计算机及其交叉学科领域的观点洞察及前沿展望。希望…...
华为OD机试真题-分割均衡字符串-2023年OD统一考试(C卷)
题目描述: 均衡串定义:字符串只包含两种字符,且两种字符的个数相同。 给定一个均衡字符串,请给出可分割成新的均衡子串的最大个数。 约定字符串中只包含大写的X和Y两种字符。 输入描述: 均衡串:XXYYXY 字符…...
基于SpringBoot的图书推荐系统的
摘 要 网络信息技术的高速发展,使得高校图书馆的服务空间日益扩大,依据个人特点的针对性服务逐渐成为新服务模式的主导趋势。对于大多数用户而言,很难在大量的学术图书馆中快速找到他们想要的材料。另外,随着时代的不断发展&…...
02_学习使用javax_ws_rs_下载文件
文章目录 1 前言2 Maven 依赖3 下载接口4 如何返回文件?5 感谢 1 前言 专栏上一篇,写了如何使用 javax.ws.rs 上传文件,那么必然的,我们得再学习学习如何下载文件😀 2 Maven 依赖 这个就不赘述了,和上一篇…...
js校验多个时间段的时间是否有交叉
参考博客: Java日期时间API系列37-----时间段是否有重叠(交集)的计算方法 Java 最优雅方式校验时间段重叠 判断是否有交叉数据 let timePeriod [{start: dateList[0].value, //时间段1的开始时间 时间格式为1130(代表11…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
