fix: webui English fix
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/* css/lightrag.css */
|
/* css/lightrag.css */
|
||||||
|
|
||||||
/* 模态框样式 */
|
/*Modal box style*/
|
||||||
.modal {
|
.modal {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 图谱节点样式 */
|
/* graph style */
|
||||||
.node {
|
.node {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
fill: var(--primary);
|
fill: var(--primary);
|
||||||
@@ -73,20 +73,14 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 添加边样式 */
|
/* edge style */
|
||||||
.link {
|
.link {
|
||||||
stroke: #999; /* 连线颜色 */
|
stroke: #999;
|
||||||
stroke-width: 2px; /* 连线粗细 */
|
stroke-width: 2px;
|
||||||
stroke-opacity: 0.6;/* 透明度 */
|
stroke-opacity: 0.8;
|
||||||
}
|
|
||||||
/* 边样式 */
|
|
||||||
.link {
|
|
||||||
stroke: #999; /* 边颜色 */
|
|
||||||
stroke-width: 2px; /* 边粗细 */
|
|
||||||
stroke-opacity: 0.8; /* 边透明度 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 箭头颜色匹配边颜色 */
|
/* Arrow color matches edge color */
|
||||||
#arrow path {
|
#arrow path {
|
||||||
fill: #999 !important; /* 覆盖默认颜色 */
|
fill: #999 !important;
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ body {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 主容器 */
|
/* main container */
|
||||||
.app-container {
|
.app-container {
|
||||||
max-width: 1600px;
|
max-width: 1600px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -23,7 +23,7 @@ body {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 导航侧边栏 */
|
/* Navigation sidebar */
|
||||||
.nav-panel {
|
.nav-panel {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 2rem;
|
top: 2rem;
|
||||||
@@ -43,14 +43,14 @@ body {
|
|||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 主内容区 */
|
/* Main content area */
|
||||||
.main-content {
|
.main-content {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
align-content: start;
|
align-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 卡片式模块 */
|
/* Card based module */
|
||||||
.card {
|
.card {
|
||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@@ -70,7 +70,7 @@ body {
|
|||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 文件上传区域 */
|
/* File upload area */
|
||||||
.file-dropzone {
|
.file-dropzone {
|
||||||
border: 2px dashed var(--border);
|
border: 2px dashed var(--border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -85,7 +85,7 @@ body {
|
|||||||
background: rgba(79, 70, 229, 0.05);
|
background: rgba(79, 70, 229, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 按钮样式 */
|
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -116,7 +116,6 @@ body {
|
|||||||
background: #059669;
|
background: #059669;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 输入框样式 */
|
|
||||||
.input-field {
|
.input-field {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.875rem;
|
padding: 0.875rem;
|
||||||
@@ -132,7 +131,7 @@ body {
|
|||||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.app-container {
|
.app-container {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -144,7 +143,6 @@ body {
|
|||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 添加按钮激活状态样式 */
|
|
||||||
.btn.active {
|
.btn.active {
|
||||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
transform: translateY(1px);
|
transform: translateY(1px);
|
||||||
@@ -230,7 +228,6 @@ body {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 添加以下CSS样式 */
|
|
||||||
.status-grid {
|
.status-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
@@ -322,13 +319,11 @@ body {
|
|||||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 加载状态 */
|
|
||||||
.status-badge.loading {
|
.status-badge.loading {
|
||||||
background: rgba(79, 70, 229, 0.1);
|
background: rgba(79, 70, 229, 0.1);
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 错误状态 */
|
|
||||||
.status-badge.error {
|
.status-badge.error {
|
||||||
background: rgba(239, 68, 68, 0.1);
|
background: rgba(239, 68, 68, 0.1);
|
||||||
color: #EF4444;
|
color: #EF4444;
|
||||||
|
@@ -261,19 +261,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showSection(sectionId) {
|
function showSection(sectionId) {
|
||||||
// 隐藏所有内容区块 Hide all content blocks
|
// Hide all content blocks
|
||||||
const sections = document.querySelectorAll('.main-content .card');
|
const sections = document.querySelectorAll('.main-content .card');
|
||||||
sections.forEach(section => {
|
sections.forEach(section => {
|
||||||
section.style.display = 'none';
|
section.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 显示目标区块 Display target block
|
// Display target block
|
||||||
const targetSection = document.getElementById(sectionId);
|
const targetSection = document.getElementById(sectionId);
|
||||||
if (targetSection) {
|
if (targetSection) {
|
||||||
targetSection.style.display = 'block';
|
targetSection.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新按钮激活状态(可选)Update button activation status (optional)
|
// Update button activation status (optional)
|
||||||
const buttons = document.querySelectorAll('.nav-menu button');
|
const buttons = document.querySelectorAll('.nav-menu button');
|
||||||
buttons.forEach(button => {
|
buttons.forEach(button => {
|
||||||
button.classList.remove('active');
|
button.classList.remove('active');
|
||||||
@@ -281,10 +281,9 @@
|
|||||||
event.target.classList.add('active');
|
event.target.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化显示文档管理模块 Initialize the display document management module
|
// Initialize the display document management module
|
||||||
showSection('documents');
|
showSection('documents');
|
||||||
</script>
|
</script>
|
||||||
<!-- 在页面底部添加 -->
|
|
||||||
<script src="js/lightrag.js"></script>
|
<script src="js/lightrag.js"></script>
|
||||||
<script src="js/graph.js"></script>
|
<script src="js/graph.js"></script>
|
||||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||||
|
@@ -38,7 +38,7 @@ async function getGraph(label) {
|
|||||||
node.id = Date.now().toString(36) + Math.random().toString(36).substring(2); // 使用 crypto.randomUUID() 生成唯一 UUID
|
node.id = Date.now().toString(36) + Math.random().toString(36).substring(2); // 使用 crypto.randomUUID() 生成唯一 UUID
|
||||||
});
|
});
|
||||||
|
|
||||||
// 严格验证边数据 Strictly verify edge data
|
// Strictly verify edge data
|
||||||
const edges = (rawData.edges || []).map(edge => {
|
const edges = (rawData.edges || []).map(edge => {
|
||||||
const sourceNode = nodes.find(n => n.labels.includes(edge.source));
|
const sourceNode = nodes.find(n => n.labels.includes(edge.source));
|
||||||
const targetNode = nodes.find(n => n.labels.includes(edge.target)
|
const targetNode = nodes.find(n => n.labels.includes(edge.target)
|
||||||
@@ -72,20 +72,19 @@ async function renderGraph(label) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
const svg = d3.select("#graph-svg");
|
const svg = d3.select("#graph-svg");
|
||||||
const width = svg.node().clientWidth;
|
const width = svg.node().clientWidth;
|
||||||
const height = svg.node().clientHeight;
|
const height = svg.node().clientHeight;
|
||||||
|
|
||||||
//
|
|
||||||
svg.selectAll("*").remove();
|
svg.selectAll("*").remove();
|
||||||
|
|
||||||
// 创建力导向图布局 Create a force oriented diagram layout
|
// Create a force oriented diagram layout
|
||||||
const simulation = d3.forceSimulation(data.nodes)
|
const simulation = d3.forceSimulation(data.nodes)
|
||||||
.force("charge", d3.forceManyBody().strength(-300))
|
.force("charge", d3.forceManyBody().strength(-300))
|
||||||
.force("center", d3.forceCenter(width / 2, height / 2));
|
.force("center", d3.forceCenter(width / 2, height / 2));
|
||||||
|
|
||||||
// 添加连线(如果存在有效边) Add a connection (if there are valid edges)
|
// Add a connection (if there are valid edges)
|
||||||
if (data.edges.length > 0) {
|
if (data.edges.length > 0) {
|
||||||
simulation.force("link",
|
simulation.force("link",
|
||||||
d3.forceLink(data.edges)
|
d3.forceLink(data.edges)
|
||||||
@@ -94,9 +93,7 @@ async function renderGraph(label) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw nodes
|
||||||
|
|
||||||
// 绘制节点 Draw nodes
|
|
||||||
const nodes = svg.selectAll(".node")
|
const nodes = svg.selectAll(".node")
|
||||||
.data(data.nodes)
|
.data(data.nodes)
|
||||||
.enter()
|
.enter()
|
||||||
@@ -123,21 +120,21 @@ async function renderGraph(label) {
|
|||||||
.attr("d", "M0,0 L10,5 L0,10 Z")
|
.attr("d", "M0,0 L10,5 L0,10 Z")
|
||||||
.attr("fill", "#999");
|
.attr("fill", "#999");
|
||||||
|
|
||||||
// 绘制边(带箭头) Draw edges (with arrows)
|
// Draw edges (with arrows)
|
||||||
const links = svg.selectAll(".link")
|
const links = svg.selectAll(".link")
|
||||||
.data(data.edges)
|
.data(data.edges)
|
||||||
.enter()
|
.enter()
|
||||||
.append("line")
|
.append("line")
|
||||||
.attr("class", "link")
|
.attr("class", "link")
|
||||||
.attr("marker-end", "url(#arrow-out)"); // 始终在 target 侧绘制箭头 Always draw arrows on the target side
|
.attr("marker-end", "url(#arrow-out)"); // Always draw arrows on the target side
|
||||||
|
|
||||||
// 边样式配置 Edge style configuration
|
// Edge style configuration
|
||||||
links
|
links
|
||||||
.attr("stroke", "#999")
|
.attr("stroke", "#999")
|
||||||
.attr("stroke-width", 2)
|
.attr("stroke-width", 2)
|
||||||
.attr("stroke-opacity", 0.8);
|
.attr("stroke-opacity", 0.8);
|
||||||
|
|
||||||
// 绘制标签(带背景框) Draw label (with background box)
|
// Draw label (with background box)
|
||||||
const labels = svg.selectAll(".label")
|
const labels = svg.selectAll(".label")
|
||||||
.data(data.nodes)
|
.data(data.nodes)
|
||||||
.enter()
|
.enter()
|
||||||
@@ -148,16 +145,16 @@ async function renderGraph(label) {
|
|||||||
.attr("dy", "0.3em")
|
.attr("dy", "0.3em")
|
||||||
.attr("fill", "#333");
|
.attr("fill", "#333");
|
||||||
|
|
||||||
// 更新位置 Update Location
|
// Update Location
|
||||||
simulation.on("tick", () => {
|
simulation.on("tick", () => {
|
||||||
links
|
links
|
||||||
.attr("x1", d => {
|
.attr("x1", d => {
|
||||||
// 计算源节点到目标节点的方向向量 Calculate the direction vector from the source node to the target node
|
// Calculate the direction vector from the source node to the target node
|
||||||
const dx = d.target.x - d.source.x;
|
const dx = d.target.x - d.source.x;
|
||||||
const dy = d.target.y - d.source.y;
|
const dy = d.target.y - d.source.y;
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
if (distance === 0) return d.source.x; // 避免除以零 Avoid dividing by zero
|
if (distance === 0) return d.source.x; // 避免除以零 Avoid dividing by zero
|
||||||
// 根据半径 10 调整起点坐标(源节点边缘)Adjust the starting point coordinates (source node edge) based on radius 10
|
// Adjust the starting point coordinates (source node edge) based on radius 10
|
||||||
return d.source.x + (dx / distance) * 10;
|
return d.source.x + (dx / distance) * 10;
|
||||||
})
|
})
|
||||||
.attr("y1", d => {
|
.attr("y1", d => {
|
||||||
@@ -168,7 +165,7 @@ async function renderGraph(label) {
|
|||||||
return d.source.y + (dy / distance) * 10;
|
return d.source.y + (dy / distance) * 10;
|
||||||
})
|
})
|
||||||
.attr("x2", d => {
|
.attr("x2", d => {
|
||||||
// 根据半径 10 调整终点坐标(目标节点边缘) Adjust the endpoint coordinates (target node edge) based on a radius of 10
|
// Adjust the endpoint coordinates (target node edge) based on a radius of 10
|
||||||
const dx = d.target.x - d.source.x;
|
const dx = d.target.x - d.source.x;
|
||||||
const dy = d.target.y - d.source.y;
|
const dy = d.target.y - d.source.y;
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
@@ -183,7 +180,7 @@ async function renderGraph(label) {
|
|||||||
return d.target.y - (dy / distance) * 10;
|
return d.target.y - (dy / distance) * 10;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新节点和标签的位置(保持不变) Update the position of nodes and labels (keep unchanged)
|
// Update the position of nodes and labels (keep unchanged)
|
||||||
nodes
|
nodes
|
||||||
.attr("cx", d => d.x)
|
.attr("cx", d => d.x)
|
||||||
.attr("cy", d => d.y);
|
.attr("cy", d => d.y);
|
||||||
@@ -193,7 +190,7 @@ async function renderGraph(label) {
|
|||||||
.attr("y", d => d.y + 4);
|
.attr("y", d => d.y + 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 拖拽逻辑 Drag and drop logic
|
// Drag and drop logic
|
||||||
function dragStarted(event, d) {
|
function dragStarted(event, d) {
|
||||||
if (!event.active) simulation.alphaTarget(0.3).restart();
|
if (!event.active) simulation.alphaTarget(0.3).restart();
|
||||||
d.fx = d.x;
|
d.fx = d.x;
|
||||||
|
Reference in New Issue
Block a user