jsplumb当浏览器窗口大小变化时,自适应(重新绘制端点和连线)

本文介绍了如何使用jsplumb库解决ER图在不同浏览器窗口大小下不自适应的问题,通过监听窗口调整事件并调用repaintEverything方法实现图形的动态调整。同时提醒读者注意设置container的position样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用场景

最近有个需求是绘制一个ER图,将关系图上的节点或者边的属性与数据表中的字段进行映射配置。
可能是我的容器container的宽高不是px,而是百分比或者vw,vh之类的。当浏览器窗口大小变化时,该区域的ER图并没有自适应。
那就使用window.onresize解决问题吧。

解决

监听浏览器窗口变化,重新绘制点和线。

window.addEventListener('resize', () => {
	this.jsplumbInstance.repaintEverything()
})

这样就ok啦。

tip

说一句题外话,顺便记录一下,在使用jsplumb时,一定要为container设置样式:position: relative;

import sensor, image, time from pyb import LED import ustruct from pyb import UART from pyb import Pin import pyb # 初始化UART uart = UART(3, 115200, timeout_char=200) uart.init(115200, bits=8, parity=None, stop=1) # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time=2000) sensor.set_auto_gain(False) sensor.set_auto_exposure(False, exposure_us=35000) clock = time.clock() # 初始化引脚LED pin1 = Pin('P1', Pin.IN, Pin.PULL_UP) led = pyb.LED(3) def sending_data(x1, y1, x2, y2, x3, y3, x4, y4, r1, r2, g1, g2): # 打包数据并发送 data = ustruct.pack("<bbhhhhhhhhhhhhb", 0xa3, 0xb3, int(x1), int(y1), int(x2), int(y2), int(x3), int(y3), int(x4), int(y4), int(r1), int(r2), int(g1), int(g2), 0xc3) uart.write(data) def keys(): # 按键检测函数(根据实际需求实现) pass # 计算两条直线的交点(线段范围内) def line_intersection(line1, line2): # line1: 由两点组成的元组 ((x1,y1), (x2,y2)) # line2: 由两点组成的元组 ((x3,y3), (x4,y4)) (x1, y1), (x2, y2) = line1 (x3, y3), (x4, y4) = line2 # 计算分母(避免除以零) denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) if denom == 0: return None # 平行线,无交点 # 计算分子 t_num = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4) u_num = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) t = t_num / denom u = u_num / denom # 检查交点是否在线段范围内 if 0 <= t <= 1 and 0 <= u <= 1: x = int(x1 + t * (x2 - x1)) y = int(y1 + t * (y2 - y1)) return (x, y) else: return None # 交点在线段外 # 红色绿色阈值 red_threshold = [(99, 100, -7, 50, -60, 32)] green_threshold = [(52, 100, -19, -128, -128, 127), (0, 100, -128, -24, -128, 127)] while True: clock.tick() img = sensor.snapshot()#.lens_corr(strength=1.0, zoom=1.1) img.gaussian(1, unsharp=True) # 高斯滤波增强图像 # 查找矩形 rects = img.find_rects(threshold=30000, ROI=(114, 68, 102, 100)) led.on() # 打开LED指示正在运行 max_area = 0 max_rect = None # 查找最大矩形 for rect in rects: area = rect.w() * rect.h() if area > max_area: max_area = area max_rect = rect if max_rect: # 获取矩形角点 corners = max_rect.corners() x1, y1 = corners[0] x2, y2 = corners[1] x3, y3 = corners[2] x4, y4 = corners[3] # 绘制原始角点(不同大小的圆) img.draw_circle(x1, y1, 5, color=(0, 25, 0)) # 绿色小圆 img.draw_circle(x2, y2, 10, color=(0, 25, 0)) # 绿色中圆 img.draw_circle(x3, y3, 15, color=(0, 25, 0)) # 绿色大圆 img.draw_circle(x4, y4, 20, color=(0, 25, 0)) # 绿色最大圆 # 绘制矩形边框(蓝色线) img.draw_line(x1, y1, x2, y2, color=(0, 0, 255)) # 上边 - 蓝色 img.draw_line(x2, y2, x3, y3, color=(0, 0, 255)) # 右边 - 蓝色 img.draw_line(x3, y3, x4, y4, color=(0, 0, 255)) # 底边 - 蓝色 img.draw_line(x4, y4, x1, y1, color=(0, 0, 255)) # 左边 - 蓝色 # ====== 每条边六等分(5个等分点)====== division_points = [] # 存储所有等分点(4条边,每条边5个点) # 计算每条边的六等分点(5个点) for i in range(4): start = corners[i] end = corners[(i + 1) % 4] # 计算当前边的5个等分点 points = [] for j in range(1, 6): # j从1到5,对应5个等分点 ratio = j / 6.0 # 等分比例 x = int(start[0] + ratio * (end[0] - start[0])) y = int(start[1] + ratio * (end[1] - start[1])) points.append((x, y)) # 将1/32/3位置的点(即j=2j=4)改为绿色,其余为黄色 if j == 2 or j == 4: # 1/32/3位置 img.draw_circle(x, y, 3, color=(0, 255, 0)) # 绿色圆点 else: img.draw_circle(x, y, 3, color=(255, 255, 0)) # 黄色圆点 division_points.append(points) # 将当前边的点加入列表 # 打印所有等分点坐标(调试用) print("六等分点坐标:") for i, points in enumerate(division_points): for j, point in enumerate(points): print(f"边{i+1} 点{j+1}: ({point[0]}, {point[1]})") # ====== 按规则连接等分点并计算黄色连线交点 ====== # 存储黄色连线(用于计算交点) yellow_lines = [] for i in range(5): # 每个边有5个点 # 判断是否是1/32/3位置的连线(i=1i=3) if i == 1 or i == 3: # 1/32/3位置的连线 line_color = (0, 255, 0) # 绿色连线 else: line_color = (255, 255, 0) # 黄色连线 # 记录黄色连线的两个端点(用于后续计算交点) line1 = (division_points[0][i], division_points[2][4-i]) line2 = (division_points[1][i], division_points[3][4-i]) yellow_lines.append(line1) yellow_lines.append(line2) # 第一条边(上边)第i点 -> 第三条边(底边)(4-i)点 img.draw_line( division_points[0][i][0], division_points[0][i][1], division_points[2][4-i][0], division_points[2][4-i][1], color=line_color ) # 第二条边(右边)第i点 -> 第四条边(左边)(4-i)点 img.draw_line( division_points[1][i][0], division_points[1][i][1], division_points[3][4-i][0], division_points[3][4-i][1], color=line_color ) # 计算黄色连线之间的交点并标记 print("黄色连线交点坐标:") # 遍历所有黄色连线,计算两两之间的交点 for i in range(len(yellow_lines)): for j in range(i + 1, len(yellow_lines)): line_a = yellow_lines[i] line_b = yellow_lines[j] intersection = line_intersection(line_a, line_b) if intersection: x, y = intersection # 用红色圆圈标记交点 img.draw_circle(x, y, 1, color=(255, 0, 0), thickness=2) print(f"交点 {i+1}-{j+1}: ({x}, {y})") print("角点坐标:", x1, y1, x2, y2, x3, y3, x4, y4) else: # 未找到矩形清零坐标 x1 = y1 = x2 = y2 = x3 = y3 = x4 = y4 = 0 # 红色斑点检测 red = img.find_blobs(red_threshold) if red: r = red[0] img.draw_cross(r.cx(), r.cy(), color=(10, 10, 10)) # 绘制十字标记 r1 = r.cx() r2 = r.cy() else: r1 = r2 = 0 # 绿色斑点检测 gree = img.find_blobs(green_threshold) if gree: g = gree[0] img.draw_cross(g.cx(), g.cy(), color=(255, 0, 0)) # 绘制红色十字标记 g1 = g.cx() g2 = g.cy() else: g1 = g2 = 0 # 发送所有数据 x1 = 154 y1 =145 sending_data(x1, y1, x2, y2, x3, y3, x4, y4, r1, r2, g1, g2) 注释黄线绿线,黄圈绿圈,给我完整代码
最新发布
07-18
function connected_bw = connectbw(bw) cc = bwconncomp(bw); props = regionprops(cc, ‘BoundingBox’, ‘PixelList’); connected_bw = bw; % 最右端 最左端 rightmost_points = []; leftmost_points = []; for i = 1:length(props) rightmost = max(props(i).PixelList(:,1)); right_y = props(i).PixelList(props(i).PixelList(:,1) == rightmost, 2); leftmost = min(props(i).PixelList(:,1)); left_y = props(i).PixelList(props(i).PixelList(:,1) == leftmost, 2); rightmost_points = [rightmost_points; rightmost, mean(right_y)]; leftmost_points = [leftmost_points; leftmost, mean(left_y)]; end % 初始化 connected = false(1, length(props)); current_idx = 1; connected(current_idx) = true; % 循环遍历 while sum(connected) < length(props) right_point = rightmost_points(current_idx, :); min_dist = Inf; % 最小距离 next_idx = -1; for i = 1:length(props) if ~connected(i) % 只考虑未连接的连通域 left_point = leftmost_points(i, :); dist = sqrt((right_point(1) - left_point(1))^2 + (right_point(2) - left_point(2))^2); if dist < min_dist % 找到更近的连通域 min_dist = dist; next_idx = i; end end end if next_idx ~= -1 right_point = rightmost_points(current_idx, :); left_point = leftmost_points(next_idx, :); x_coords = [right_point(1), left_point(1)]; y_coords = [right_point(2), left_point(2)]; % 插值连接 line_points = round([linspace(x_coords(1), x_coords(2), 50)', ... linspace(y_coords(1), y_coords(2), 50)']); for k = 1:size(line_points, 1) connected_bw(line_points(k,2), line_points(k,1)) = 1; end % 已连接标志 connected(next_idx) = true; % 更新连通域索引 current_idx = next_idx; end end 我想修改这个代码,使其能够提取所有连通域的边界,然后对最大的10个连通域进行操作,从最大的连通域开始,先在起始端附近寻找最近的边界点,然后进行连线,再在终止端附近寻找最近的边界点连线,然后处理第二大连通域,又由于处理第一大连通域在起始端附近寻找最近连通域的最近边界点可能刚好是第二大连通域的一端,此只需要处理第二大连通域的另一端,去寻找距离最近的边界点,然后连线,依此类推,如果连线长度超过50则连虚线,小于50则连实线,提供完整代码
03-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值