JsPlumb là thư viện JavaScript mạnh mẽ giúp kết nối các phần tử HTML bằng mũi tên, đường cong, đoạn thẳng... Phù hợp phát triển ứng dụng biểu đồ, mô hình hóa. Dưới đây là hướng dẫn chi tiết cách tạo sơ đồ luồng tương tác với nhiều hiệu ứng phức tạp.
Cấu hình ban đầu
1. Tải thư viện cần thiết:
2. Khởi tạo giao diện kéo thả:
// Khởi tạo vùng chứa trái và giữa
// Cấu hình kéo thả
$("#vungMau .phanTu").draggable({
helper: "clone",
scope: "phanTu"
});
$("#vungChinh").droppable({
scope: "phanTu",
drop: function(e, ui) {
TaoPhanTu(ui, $(this));
}
});
Tạo sơ đồ luồng cơ bản
// Định nghĩa kiểu nối
var mauNoi = {
strokeStyle: "#1e8151",
lineWidth: 2,
radius: 5
};
var mauNoiHoatDong = {
lineWidth: 3,
strokeStyle: "#216477"
};
// Hàm tạo phần tử mới
function TaoPhanTu(ui, chua) {
var maPhanTu = $(ui.draggable).attr("id");
var idMoi = maPhanTu + "_" + ++dem;
$(chua).append(''+$(ui.helper).html()+'');
// Thêm điểm nối
jsPlumb.addEndpoint(idMoi, { anchors: "RightMiddle" }, {
endpoint: ["Dot", { radius: 7 }],
connectorStyle: mauNoi,
isSource: true,
isTarget: true,
maxConnections: -1
});
// Cấu hình kéo thả
$("#" + idMoi).draggable({
containment: "parent",
drag: function(e, ui) {
CapNhatNoi();
}
});
}
Hiệu ứng nối đa dạng
Thay đổi kiểu nối qua dropdown:
$("#loaiNoi").change(function() {
var loai = $(this).val();
var mau = loai === "straight" ? "green" : loai === "bezier" ? "orange" : "red";
$("#vungChinh .phanTu").each(function() {
var diemNoi = jsPlumb.getEndpoints(this.id);
diemNoi.forEach(dp => {
dp.connector = [loai.charAt(0).toUpperCase() + loai.slice(1), {}];
dp.connectorStyle.strokeStyle = mau;
});
});
});
Chọn và di chuyển nhiều phần tử
// Lớp quản lý chọn nhiều
function QuanLyChon(phamVi) {
this.phamVi = phamVi;
this.dangChon = false;
this.khoiTao();
}
QuanLyChon.prototype.khoiTao = function() {
var self = this;
$(document).mousedown(function(e) {
if ($(e.target).closest(self.phamVi).length) {
self.batDauChon(e);
}
});
};
QuanLyChon.prototype.batDauChon = function(e) {
this.diemBatDau = {x: e.pageX, y: e.pageY};
this.dangChon = true;
this.taoKhuVucChon();
};
QuanLyChon.prototype.taoKhuVucChon = function() {
this.khuVucChon = $("").css({
position: "absolute",
border: "1px dashed #0099FF",
opacity: 0.5,
zIndex: 1000
}).appendTo("#vungChinh");
};
QuanLyChon.prototype.ketThucChon = function() {
this.dangChon = false;
this.khuVucChon.remove();
};
// Di chuyển đồng loạt
function DiChuyenDongBo(phanTu, delta) {
$(".phanTu.chon").each(function() {
$(this).css({
left: parseInt($(this).css("left")) + delta.x,
top: parseInt($(this).css("top")) + delta.y
});
});
jsPlumb.repaintEverything();
}
Canh chỉnh và xoay phần tử
// Canh lề trái
function CanhTrai() {
var phanTu = $(".phanTu.chon");
var viTri = Math.min(...phanTu.map(i => parseInt($(i).css("left"))));
phanTu.css("left", viTri);
jsPlumb.repaintEverything();
}
// Canh giữa
function CanhGiua() {
var phanTu = $(".phanTu.chon");
var viTri = Math.min(...phanTu.map(i => parseInt($(i).css("left")) + $(i).width()/2));
phanTu.css("left", viTri - $(i).width()/2);
jsPlumb.repaintEverything();
}
// Xoay phần tử
function Xoay(direction) {
var phanTu = $(".phanTu.chon");
phanTu.each(function() {
var goc = parseInt($(this).css("transform").replace(/[^0-9-]/g,"")) || 0;
$(this).css("transform", "rotate(" + (goc + direction*45) + "deg)");
});
jsPlumb.repaintEverything();
}
Xóa phần tử và kết nối
function XoaPhanTu() {
$(".phanTu.chon").each(function() {
jsPlumb.remove(this);
$(this).remove();
});
jsPlumb.repaintEverything();
}
Nguyên lý cốt lõi: Sử dụng các điểm nối được quản lý bởi JsPlumb để tạo kết nối động giữa các phần tử. Khi di chuyển phần tử, gọi jsPlumb.repaintEverything() để cập nhật kết nối.
Đăng vào ngày 10 tháng 8 lúc 20:36