dev
This commit is contained in:
622
wiremap/故障图生成器.html
Normal file
622
wiremap/故障图生成器.html
Normal file
@@ -0,0 +1,622 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>网络线序图生成器 (T568A/T568B)</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
#svg-container {
|
||||
margin-top: 20px;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
.control-panel {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
.control-group {
|
||||
margin-bottom: 15px;
|
||||
padding: 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.control-group h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #2c3e50;
|
||||
font-size: 18px;
|
||||
}
|
||||
select, button, input[type="checkbox"] {
|
||||
padding: 8px 12px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
}
|
||||
select:focus, button:focus {
|
||||
outline: none;
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 2px rgba(52,152,219,0.2);
|
||||
}
|
||||
button {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
.cable-fault-row {
|
||||
margin: 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.cable-fault-row select, .cable-fault-row input {
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.cable-fault-row label {
|
||||
min-width: 60px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.action-buttons button {
|
||||
flex: 1;
|
||||
}
|
||||
.copy-success {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background-color: #2ecc71;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
display: none;
|
||||
animation: fadeInOut 2s ease-in-out;
|
||||
}
|
||||
@keyframes fadeInOut {
|
||||
0% { opacity: 0; }
|
||||
20% { opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
100% { opacity: 0; }
|
||||
}
|
||||
.svg-code-container {
|
||||
margin-top: 20px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
display: none;
|
||||
}
|
||||
.svg-code-container h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
pre {
|
||||
background-color: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>网络线序图生成器 (T568A/T568B)</h1>
|
||||
|
||||
<div class="control-panel">
|
||||
<div class="control-group">
|
||||
<h3>基本设置</h3>
|
||||
<div style="display: flex; gap: 20px; align-items: center;">
|
||||
<div>
|
||||
<label for="standard">选择线序标准:</label>
|
||||
<select id="standard">
|
||||
<option value="T568A">T568A</option>
|
||||
<option value="T568B" selected>T568B</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="show-shield">屏蔽线:</label>
|
||||
<input type="checkbox" id="show-shield" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<h3>故障配置</h3>
|
||||
<div id="cable-faults"></div>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button id="generate-btn">生成网络线序图</button>
|
||||
<button id="copy-svg-btn">复制SVG代码</button>
|
||||
<button id="save-svg-btn">保存SVG文件</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="svg-container"></div>
|
||||
|
||||
<div class="svg-code-container" id="svg-code-container">
|
||||
<h3>SVG代码</h3>
|
||||
<pre id="svg-code"></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="copy-success" id="copy-success">复制成功!</div>
|
||||
|
||||
<script>
|
||||
// 初始化故障配置面板
|
||||
function initFaultConfig() {
|
||||
const cableIds = ['1', '2', '3', '6', '4', '5', '7', '8', 'S'];
|
||||
const faultConfigDiv = document.getElementById('cable-faults');
|
||||
|
||||
cableIds.forEach(id => {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'cable-fault-row';
|
||||
|
||||
const label = document.createElement('span');
|
||||
label.textContent = `线${id}:`;
|
||||
|
||||
const faultSelect = document.createElement('select');
|
||||
faultSelect.id = `fault-type-${id}`;
|
||||
faultSelect.innerHTML = `
|
||||
<option value="none">正常</option>
|
||||
<option value="open">开路</option>
|
||||
<option value="short">短路</option>
|
||||
<option value="cross">交叉</option>
|
||||
<option value="bridge">跨接</option>
|
||||
`;
|
||||
|
||||
const shortTargetSelect = document.createElement('select');
|
||||
shortTargetSelect.id = `short-target-${id}`;
|
||||
shortTargetSelect.style.display = 'none';
|
||||
shortTargetSelect.innerHTML = cableIds
|
||||
.filter(targetId => targetId !== id)
|
||||
.map(targetId => `<option value="${targetId}">线${targetId}</option>`)
|
||||
.join('');
|
||||
|
||||
const shortPositionSelect = document.createElement('select');
|
||||
shortPositionSelect.id = `short-position-${id}`;
|
||||
shortPositionSelect.style.display = 'none';
|
||||
shortPositionSelect.innerHTML = `
|
||||
<option value="start">头端</option>
|
||||
<option value="end">尾端</option>
|
||||
`;
|
||||
|
||||
const shortDistanceInput = document.createElement('input');
|
||||
shortDistanceInput.id = `short-distance-${id}`;
|
||||
shortDistanceInput.type = 'number';
|
||||
shortDistanceInput.min = '0';
|
||||
shortDistanceInput.max = '100';
|
||||
shortDistanceInput.step = '0.1';
|
||||
shortDistanceInput.value = '1.1';
|
||||
shortDistanceInput.style.width = '80px';
|
||||
shortDistanceInput.placeholder = '短路距离(m)';
|
||||
shortDistanceInput.style.display = 'none';
|
||||
|
||||
const bridgeTargetSelect = document.createElement('select');
|
||||
bridgeTargetSelect.id = `bridge-target-${id}`;
|
||||
bridgeTargetSelect.style.display = 'none';
|
||||
bridgeTargetSelect.innerHTML = cableIds
|
||||
.filter(targetId => targetId !== id)
|
||||
.map(targetId => `<option value="${targetId}">线${targetId}</option>`)
|
||||
.join('');
|
||||
|
||||
faultSelect.addEventListener('change', function() {
|
||||
const isOpen = this.value === 'open';
|
||||
const isShort = this.value === 'short';
|
||||
const isCross = this.value === 'cross';
|
||||
const isBridge = this.value === 'bridge';
|
||||
|
||||
// 处理交叉故障的联动隐藏和自动设置
|
||||
if (isCross) {
|
||||
let crossPairId;
|
||||
if (id === '1') crossPairId = '2';
|
||||
else if (id === '2') crossPairId = '1';
|
||||
else if (id === '3') crossPairId = '6';
|
||||
else if (id === '6') crossPairId = '3';
|
||||
else if (id === '4') crossPairId = '5';
|
||||
else if (id === '5') crossPairId = '4';
|
||||
else if (id === '7') crossPairId = '8';
|
||||
else if (id === '8') crossPairId = '7';
|
||||
|
||||
if (crossPairId) {
|
||||
const crossPairSelect = document.getElementById(`fault-type-${crossPairId}`);
|
||||
const crossPairRow = crossPairSelect.closest('.cable-fault-row');
|
||||
crossPairRow.style.display = 'none';
|
||||
// 自动设置对应线对的交叉状态
|
||||
crossPairSelect.value = 'cross';
|
||||
}
|
||||
} else {
|
||||
// 当取消交叉时,显示对应的线对
|
||||
let crossPairId;
|
||||
if (id === '1') crossPairId = '2';
|
||||
else if (id === '2') crossPairId = '1';
|
||||
else if (id === '3') crossPairId = '6';
|
||||
else if (id === '6') crossPairId = '3';
|
||||
else if (id === '4') crossPairId = '5';
|
||||
else if (id === '5') crossPairId = '4';
|
||||
else if (id === '7') crossPairId = '8';
|
||||
else if (id === '8') crossPairId = '7';
|
||||
|
||||
if (crossPairId) {
|
||||
const crossPairRow = document.getElementById(`fault-type-${crossPairId}`).closest('.cable-fault-row');
|
||||
crossPairRow.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
leftDistanceInput.style.display = isOpen ? 'inline' : 'none';
|
||||
rightDistanceInput.style.display = isOpen ? 'inline' : 'none';
|
||||
shortTargetSelect.style.display = isShort ? 'inline' : 'none';
|
||||
shortPositionSelect.style.display = isShort ? 'inline' : 'none';
|
||||
shortDistanceInput.style.display = isShort ? 'inline' : 'none';
|
||||
bridgeTargetSelect.style.display = isBridge ? 'inline' : 'none';
|
||||
});
|
||||
|
||||
const leftDistanceInput = document.createElement('input');
|
||||
leftDistanceInput.id = `fault-distance-left-${id}`;
|
||||
leftDistanceInput.type = 'number';
|
||||
leftDistanceInput.min = '0';
|
||||
leftDistanceInput.max = '100';
|
||||
leftDistanceInput.step = '0.1';
|
||||
leftDistanceInput.value = '10.0';
|
||||
leftDistanceInput.style.width = '80px';
|
||||
leftDistanceInput.placeholder = '左端距离(m)';
|
||||
leftDistanceInput.style.display = 'none';
|
||||
|
||||
const rightDistanceInput = document.createElement('input');
|
||||
rightDistanceInput.id = `fault-distance-right-${id}`;
|
||||
rightDistanceInput.type = 'number';
|
||||
rightDistanceInput.min = '0';
|
||||
rightDistanceInput.max = '100';
|
||||
rightDistanceInput.step = '0.1';
|
||||
rightDistanceInput.value = '10.0';
|
||||
rightDistanceInput.style.width = '80px';
|
||||
rightDistanceInput.placeholder = '右端距离(m)';
|
||||
rightDistanceInput.style.display = 'none';
|
||||
|
||||
faultSelect.addEventListener('change', function() {
|
||||
const isOpen = this.value === 'open';
|
||||
leftDistanceInput.style.display = isOpen ? 'inline' : 'none';
|
||||
rightDistanceInput.style.display = isOpen ? 'inline' : 'none';
|
||||
});
|
||||
|
||||
row.appendChild(label);
|
||||
row.appendChild(faultSelect);
|
||||
row.appendChild(leftDistanceInput);
|
||||
row.appendChild(rightDistanceInput);
|
||||
row.appendChild(shortTargetSelect);
|
||||
row.appendChild(shortPositionSelect);
|
||||
row.appendChild(shortDistanceInput);
|
||||
row.appendChild(bridgeTargetSelect);
|
||||
faultConfigDiv.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
// 页面加载时初始化故障配置
|
||||
initFaultConfig();
|
||||
|
||||
// 生成SVG并显示代码
|
||||
document.getElementById('generate-btn').addEventListener('click', function() {
|
||||
const standard = document.getElementById('standard').value;
|
||||
const showShield = document.getElementById('show-shield').checked;
|
||||
const faultConfig = {};
|
||||
|
||||
const cableIds = ['1', '2', '3', '6', '4', '5', '7', '8'];
|
||||
if (showShield) {
|
||||
cableIds.push('S');
|
||||
}
|
||||
|
||||
cableIds.forEach(id => {
|
||||
const faultType = document.getElementById(`fault-type-${id}`).value;
|
||||
const leftDistance = document.getElementById(`fault-distance-left-${id}`).value;
|
||||
const rightDistance = document.getElementById(`fault-distance-right-${id}`).value;
|
||||
const shortTarget = document.getElementById(`short-target-${id}`).value;
|
||||
const shortPosition = document.getElementById(`short-position-${id}`).value;
|
||||
const shortDistance = document.getElementById(`short-distance-${id}`).value;
|
||||
const bridgeTarget = document.getElementById(`bridge-target-${id}`).value;
|
||||
|
||||
faultConfig[id] = {
|
||||
type: faultType,
|
||||
leftDistance: faultType === 'open' ? parseFloat(leftDistance) : null,
|
||||
rightDistance: faultType === 'open' ? parseFloat(rightDistance) : null,
|
||||
shortTarget: faultType === 'short' ? shortTarget : null,
|
||||
shortPosition: faultType === 'short' ? shortPosition : null,
|
||||
shortDistance: faultType === 'short' ? parseFloat(shortDistance) : null,
|
||||
bridgeTarget: faultType === 'bridge' ? bridgeTarget : null
|
||||
};
|
||||
});
|
||||
|
||||
const svgElement = generateSVG(standard, faultConfig, showShield);
|
||||
|
||||
// 显示SVG代码
|
||||
const svgCode = new XMLSerializer().serializeToString(svgElement);
|
||||
document.getElementById('svg-code').textContent = svgCode;
|
||||
document.getElementById('svg-code-container').style.display = 'block';
|
||||
});
|
||||
|
||||
// 复制SVG代码
|
||||
document.getElementById('copy-svg-btn').addEventListener('click', function() {
|
||||
const svgCode = document.getElementById('svg-code').textContent;
|
||||
if (svgCode) {
|
||||
navigator.clipboard.writeText(svgCode).then(function() {
|
||||
const copySuccess = document.getElementById('copy-success');
|
||||
copySuccess.style.display = 'block';
|
||||
setTimeout(function() {
|
||||
copySuccess.style.display = 'none';
|
||||
}, 2000);
|
||||
}).catch(function(err) {
|
||||
console.error('无法复制: ', err);
|
||||
alert('复制失败,请手动复制');
|
||||
});
|
||||
} else {
|
||||
alert('请先生成SVG图像');
|
||||
}
|
||||
});
|
||||
|
||||
// 保存SVG文件
|
||||
document.getElementById('save-svg-btn').addEventListener('click', function() {
|
||||
const svgCode = document.getElementById('svg-code').textContent;
|
||||
if (svgCode) {
|
||||
const fileName = prompt('请输入要保存的文件名 (不包含扩展名):', '网络线序图');
|
||||
if (fileName === null) { // 用户取消输入
|
||||
return;
|
||||
}
|
||||
const fullFileName = fileName.trim() === '' ? '网络线序图.svg' : fileName + '.svg';
|
||||
|
||||
const blob = new Blob([svgCode], {type: 'image/svg+xml'});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = fullFileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
} else {
|
||||
alert('请先生成SVG图像');
|
||||
}
|
||||
});
|
||||
|
||||
function generateSVG(standard, faultConfig, showShield) {
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
const svg = document.createElementNS(svgNS, "svg");
|
||||
svg.setAttribute("width", "800");
|
||||
svg.setAttribute("height", "600");
|
||||
|
||||
// 添加样式
|
||||
const style = document.createElementNS(svgNS, "style");
|
||||
style.textContent = `
|
||||
.wire { stroke-width: 10; fill: none; }
|
||||
.label { font-family: Arial; font-size: 24px; font-weight: bold; }
|
||||
.solid { stroke-dasharray: none; }
|
||||
.dashed { stroke-dasharray: 30 15; }
|
||||
`;
|
||||
svg.appendChild(style);
|
||||
|
||||
// 背景
|
||||
const bg = document.createElementNS(svgNS, "rect");
|
||||
bg.setAttribute("width", "100%");
|
||||
bg.setAttribute("height", "100%");
|
||||
bg.setAttribute("fill", "#f9f9f9");
|
||||
svg.appendChild(bg);
|
||||
|
||||
// 线缆数据(T568A 和 T568B 的区别)
|
||||
const baseConfig = (standard === "T568A") ? [
|
||||
{ id: 1, color: "#009900", y: 50, endY: 50, dash: true }, // 白绿(T568A)
|
||||
{ id: 2, color: "#009900", y: 100, endY: 100, dash: false }, // 绿(T568A)
|
||||
{ id: 3, color: "#ff9900", y: 170, endY: 170, dash: true }, // 白橙(T568A)
|
||||
{ id: 6, color: "#ff9900", y: 220, endY: 220, dash: false }, // 橙(T568A)
|
||||
{ id: 4, color: "#0000ff", y: 300, endY: 300, dash: false }, // 蓝
|
||||
{ id: 5, color: "#0000ff", y: 350, endY: 350, dash: true }, // 白蓝
|
||||
{ id: 7, color: "#996633", y: 430, endY: 430, dash: true }, // 白棕
|
||||
{ id: 8, color: "#996633", y: 480, endY: 480, dash: false }, // 棕
|
||||
{ id: 'S', color: "#777777", y: 550, endY: 550, dash: false } // 屏蔽层(可选)
|
||||
] : [
|
||||
{ id: 1, color: "#ff9900", y: 50, endY: 50, dash: true }, // 白橙(T568B)
|
||||
{ id: 2, color: "#ff9900", y: 100, endY: 100, dash: false }, // 橙(T568B)
|
||||
{ id: 3, color: "#009900", y: 170, endY: 170, dash: true }, // 白绿(T568B)
|
||||
{ id: 6, color: "#009900", y: 220, endY: 220, dash: false }, // 绿(T568B)
|
||||
{ id: 4, color: "#0000ff", y: 300, endY: 300, dash: false }, // 蓝
|
||||
{ id: 5, color: "#0000ff", y: 350, endY: 350, dash: true }, // 白蓝
|
||||
{ id: 7, color: "#996633", y: 430, endY: 430, dash: true }, // 白棕
|
||||
{ id: 8, color: "#996633", y: 480, endY: 480, dash: false }, // 棕
|
||||
{ id: 'S', color: "#777777", y: 550, endY: 550, dash: false } // 屏蔽层(可选)
|
||||
];
|
||||
|
||||
// 根据是否显示屏蔽线过滤配置
|
||||
const filteredConfig = showShield ? baseConfig : baseConfig.filter(cable => cable.id !== 'S');
|
||||
|
||||
// 应用故障配置
|
||||
const cables = filteredConfig.map(cable => {
|
||||
const config = faultConfig[cable.id];
|
||||
let endY = cable.y;
|
||||
|
||||
// 处理交叉故障
|
||||
if (config.type === 'cross') {
|
||||
let crossPairId;
|
||||
if (cable.id === 1) crossPairId = 2;
|
||||
else if (cable.id === 2) crossPairId = 1;
|
||||
else if (cable.id === 3) crossPairId = 6;
|
||||
else if (cable.id === 6) crossPairId = 3;
|
||||
else if (cable.id === 4) crossPairId = 5;
|
||||
else if (cable.id === 5) crossPairId = 4;
|
||||
else if (cable.id === 7) crossPairId = 8;
|
||||
else if (cable.id === 8) crossPairId = 7;
|
||||
|
||||
if (crossPairId) {
|
||||
const crossPairCable = filteredConfig.find(c => c.id === crossPairId);
|
||||
if (crossPairCable) {
|
||||
endY = crossPairCable.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理跨接故障
|
||||
if (config.type === 'bridge' && config.bridgeTarget) {
|
||||
const bridgeTargetCable = filteredConfig.find(c => c.id.toString() === config.bridgeTarget.toString());
|
||||
if (bridgeTargetCable) {
|
||||
endY = bridgeTargetCable.y;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...cable,
|
||||
endY,
|
||||
fault: config.type,
|
||||
leftDistance: config.leftDistance,
|
||||
rightDistance: config.rightDistance,
|
||||
shortTarget: config.shortTarget,
|
||||
shortPosition: config.shortPosition,
|
||||
shortDistance: config.shortDistance,
|
||||
bridgeTarget: config.bridgeTarget
|
||||
};
|
||||
});
|
||||
|
||||
// 生成每条线缆
|
||||
cables.forEach(cable => {
|
||||
// 开始直线段
|
||||
const line1 = document.createElementNS(svgNS, "line");
|
||||
line1.setAttribute("x1", "100");
|
||||
line1.setAttribute("y1", cable.y);
|
||||
line1.setAttribute("x2", "150");
|
||||
line1.setAttribute("y2", cable.y);
|
||||
line1.setAttribute("class", `wire ${cable.dash ? 'dashed' : 'solid'}`);
|
||||
line1.setAttribute("stroke", cable.color);
|
||||
svg.appendChild(line1);
|
||||
|
||||
// 中间曲线段(如果不是开路故障)
|
||||
if (!cable.fault || cable.fault === 'none' || cable.fault === 'short' || cable.fault === 'cross' || cable.fault === 'bridge') {
|
||||
const path = document.createElementNS(svgNS, "path");
|
||||
const controlY = (cable.fault === 'cross' || cable.fault === 'bridge') ? (cable.y + cable.endY) / 2 : cable.y;
|
||||
path.setAttribute("d", `M 150,${cable.y} Q 400,${controlY} 650,${cable.endY}`);
|
||||
path.setAttribute("class", `wire ${cable.dash ? 'dashed' : 'solid'}`);
|
||||
path.setAttribute("stroke", cable.color);
|
||||
svg.appendChild(path);
|
||||
} else if (cable.fault === 'open') {
|
||||
// 开路故障时添加距离标签
|
||||
// 左侧距离标签
|
||||
const leftLabel = document.createElementNS(svgNS, "text");
|
||||
leftLabel.setAttribute("x", "180");
|
||||
leftLabel.setAttribute("y", cable.y + 5);
|
||||
leftLabel.setAttribute("text-anchor", "start");
|
||||
leftLabel.textContent = `${cable.leftDistance}m`;
|
||||
svg.appendChild(leftLabel);
|
||||
|
||||
// 右侧距离标签
|
||||
const rightLabel = document.createElementNS(svgNS, "text");
|
||||
rightLabel.setAttribute("x", "630");
|
||||
rightLabel.setAttribute("y", cable.y + 5);
|
||||
rightLabel.setAttribute("text-anchor", "end");
|
||||
rightLabel.textContent = `${cable.rightDistance}m`;
|
||||
svg.appendChild(rightLabel);
|
||||
}
|
||||
|
||||
// 结束直线段
|
||||
const line2 = document.createElementNS(svgNS, "line");
|
||||
line2.setAttribute("x1", "650");
|
||||
line2.setAttribute("y1", cable.y);
|
||||
line2.setAttribute("x2", "700");
|
||||
line2.setAttribute("y2", cable.y);
|
||||
line2.setAttribute("class", `wire ${cable.dash ? 'dashed' : 'solid'}`);
|
||||
line2.setAttribute("stroke", cable.color);
|
||||
svg.appendChild(line2);
|
||||
|
||||
// 标签
|
||||
const label1 = document.createElementNS(svgNS, "text");
|
||||
label1.setAttribute("x", "70");
|
||||
label1.setAttribute("y", cable.y + 5);
|
||||
label1.setAttribute("class", "label");
|
||||
label1.setAttribute("text-anchor", "end");
|
||||
label1.textContent = cable.id;
|
||||
svg.appendChild(label1);
|
||||
|
||||
const label2 = document.createElementNS(svgNS, "text");
|
||||
label2.setAttribute("x", "730");
|
||||
label2.setAttribute("y", cable.y + 5);
|
||||
label2.setAttribute("class", "label");
|
||||
label2.textContent = cable.id;
|
||||
svg.appendChild(label2);
|
||||
});
|
||||
|
||||
// 在所有线缆渲染完成后,渲染短路标记
|
||||
cables.forEach(cable => {
|
||||
if (cable.fault === 'short') {
|
||||
const targetCable = cables.find(c => c.id.toString() === cable.shortTarget.toString());
|
||||
if (targetCable) {
|
||||
const x = cable.shortPosition === 'start' ? 150 : 650;
|
||||
const shortLabel = document.createElementNS(svgNS, "text");
|
||||
shortLabel.setAttribute("x", x.toString());
|
||||
shortLabel.setAttribute("y", Math.min(cable.y, targetCable.y) - 10);
|
||||
shortLabel.setAttribute("text-anchor", "middle");
|
||||
shortLabel.textContent = `${cable.shortDistance}m`;
|
||||
svg.appendChild(shortLabel);
|
||||
|
||||
const dot1 = document.createElementNS(svgNS, "circle");
|
||||
dot1.setAttribute("cx", x.toString());
|
||||
dot1.setAttribute("cy", cable.y.toString());
|
||||
dot1.setAttribute("r", "8");
|
||||
dot1.setAttribute("fill", "black");
|
||||
svg.appendChild(dot1);
|
||||
|
||||
const dot2 = document.createElementNS(svgNS, "circle");
|
||||
dot2.setAttribute("cx", x.toString());
|
||||
dot2.setAttribute("cy", targetCable.y.toString());
|
||||
dot2.setAttribute("r", "8");
|
||||
dot2.setAttribute("fill", "black");
|
||||
svg.appendChild(dot2);
|
||||
|
||||
const shortLine = document.createElementNS(svgNS, "line");
|
||||
shortLine.setAttribute("x1", x.toString());
|
||||
shortLine.setAttribute("y1", cable.y.toString());
|
||||
shortLine.setAttribute("x2", x.toString());
|
||||
shortLine.setAttribute("y2", targetCable.y.toString());
|
||||
shortLine.setAttribute("stroke", "black");
|
||||
shortLine.setAttribute("stroke-width", "3");
|
||||
svg.appendChild(shortLine);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 添加到DOM
|
||||
const container = document.getElementById('svg-container');
|
||||
container.innerHTML = '';
|
||||
container.appendChild(svg);
|
||||
|
||||
return svg;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user