function drawWellConstruction(data, scale = 40) {
const graphicsScrollContainer = document.getElementById('graphicsScrollContainer');
if (!graphicsScrollContainer) {
console.error('graphicsScrollContainer не найден');
return;
}
// ОЧИЩАЕМ И НАСТРАИВАЕМ ПРОКРУТКУ
graphicsScrollContainer.innerHTML = '';
graphicsScrollContainer.style.cssText = '';
graphicsScrollContainer.style.overflow = 'auto';
graphicsScrollContainer.style.overflowX = 'auto';
graphicsScrollContainer.style.overflowY = 'scroll';
graphicsScrollContainer.style.height = '100%';
graphicsScrollContainer.style.maxHeight = '100%';
graphicsScrollContainer.style.position = 'relative';
graphicsScrollContainer.style.display = 'block';
const totalDepth = data.totalDepth;
const topReserve = 15;
const bottomReserve = 50;
const contentHeight = totalDepth * scale + topReserve;
const totalHeight = contentHeight + bottomReserve;
const headerHeight = 45;
// Получаем данные проходки
const drillingData = [];
const casingData = [];
let hasRealDrillingData = false;
if (xmlData && xmlData.drillingHeaders && xmlData.drillingHeaders.length > 0) {
const headerId = currentDrillingHeaderId || xmlData.drillingHeaders[0].id;
const headerData = xmlData.drillingDataByHeader && xmlData.drillingDataByHeader[headerId];
if (headerData && headerData.diameter && headerData.diameter.length > 0) {
headerData.diameter.forEach(dia => {
if (dia.diameter && dia.diameter > 50 && dia.diameter < 500 &&
dia.from !== undefined && dia.to !== undefined &&
(dia.to - dia.from) > 0.1) {
drillingData.push({
depthFrom: dia.from || 0,
depthTo: dia.to || 0,
diameter: dia.diameter || 112,
type: 'drilling'
});
hasRealDrillingData = true;
}
});
}
if (headerData && headerData.casing && headerData.casing.length > 0) {
headerData.casing.forEach(casing => {
if (casing.diameter && casing.diameter > 50 && casing.diameter < 500 &&
casing.from !== undefined && casing.to !== undefined &&
(casing.to - casing.from) > 0.1) {
casingData.push({
depthFrom: casing.from || 0,
depthTo: casing.to || 0,
diameter: casing.diameter || 112,
type: 'casing',
pipeType: casing.pipeType || 'Не указано'
});
hasRealDrillingData = true;
}
});
}
}
if (!hasRealDrillingData) {
graphicsScrollContainer.innerHTML = `
⚠️
Нет данных проходки для отображения конструкции
Выберите другую скважину или тип документации
`;
return;
}
// Сортируем
drillingData.sort((a, b) => a.depthFrom - b.depthFrom);
casingData.sort((a, b) => a.depthFrom - b.depthFrom);
// Находим максимальный диаметр
const allDiameters = [...drillingData.map(d => d.diameter), ...casingData.map(c => c.diameter)];
const maxDiameter = Math.max(...allDiameters, 112);
// СОЗДАЕМ КОНТЕЙНЕР
const scrollContent = document.createElement('div');
scrollContent.style.cssText = `
display: block;
width: 100%;
min-height: ${totalHeight + headerHeight + 20}px;
height: auto;
position: relative;
`;
const container = document.createElement('div');
container.style.cssText = `
position: relative;
width: 100%;
background: white;
border: 1px solid #cbd5e1;
border-radius: 4px;
margin-bottom: 20px;
`;
// Шапка
const header = document.createElement('div');
header.style.cssText = `
position: sticky;
top: 0;
z-index: 200;
display: flex;
height: ${headerHeight}px;
background: #e2e8f0;
border-bottom: 2px solid #94a3b8;
`;
const depthHeader = document.createElement('div');
depthHeader.style.cssText = `width: 60px; min-width: 60px; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.7rem; border-right: 1px solid #cbd5e1; background: #e2e8f0;`;
depthHeader.textContent = 'глубина, м';
const constructionHeader = document.createElement('div');
constructionHeader.style.cssText = `flex: 1; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.75rem; background: #e2e8f0;`;
constructionHeader.textContent = 'Конструкция скважины';
header.appendChild(depthHeader);
header.appendChild(constructionHeader);
container.appendChild(header);
// Тело
const bodyContainer = document.createElement('div');
bodyContainer.style.cssText = `
position: relative;
min-height: ${contentHeight}px;
height: auto;
`;
const body = document.createElement('div');
body.style.cssText = `display: flex; position: relative; min-height: ${contentHeight}px;`;
const depthArea = document.createElement('div');
depthArea.style.cssText = `width: 60px; background: #f8fafc; border-right: 1px solid #cbd5e1; position: relative; min-height: ${contentHeight}px; padding-top: ${topReserve}px; padding-bottom: ${bottomReserve}px;`;
const constructionArea = document.createElement('div');
constructionArea.style.cssText = `flex: 1; background: #ffffff; position: relative; min-height: ${contentHeight}px; padding-top: ${topReserve}px; padding-bottom: ${bottomReserve}px;`;
body.appendChild(depthArea);
body.appendChild(constructionArea);
bodyContainer.appendChild(body);
container.appendChild(bodyContainer);
scrollContent.appendChild(container);
graphicsScrollContainer.appendChild(scrollContent);
// Шкала глубины
const finalDepthY = totalDepth * scale + topReserve;
for (let depth = 0; depth <= totalDepth; depth += 5) {
const yPos = depth * scale + topReserve;
const line = document.createElement('div');
line.style.cssText = `position: absolute; top: ${yPos}px; left: 8px; right: 0; height: 1px; background: #cbd5e1; z-index: 10;`;
const label = document.createElement('span');
label.style.cssText = `position: absolute; right: 6px; top: ${yPos}px; font-size: 0.65rem; font-weight: 600; color: #1e293b; background: #f8fafc; padding: 0 2px; transform: translateY(-50%); z-index: 150;`;
label.textContent = depth.toString();
depthArea.appendChild(line);
depthArea.appendChild(label);
}
for (let depth = 0; depth < totalDepth; depth += 1) {
if (depth % 5 !== 0) {
const yPos = depth * scale + topReserve;
const line = document.createElement('div');
line.style.cssText = `position: absolute; top: ${yPos}px; left: 8px; right: 0; height: 1px; background: #e2e8f0; z-index: 10;`;
depthArea.appendChild(line);
}
}
// Забой
const bottomLine = document.createElement('div');
bottomLine.style.cssText = `position: absolute; top: ${finalDepthY}px; left: 0; right: 0; height: 2px; background: #e74c3c; z-index: 25;`;
depthArea.appendChild(bottomLine);
const bottomLabel = document.createElement('span');
bottomLabel.style.cssText = `position: absolute; right: 6px; top: ${finalDepthY}px; font-weight: 700; font-size: 0.7rem; color: #e74c3c; background: #f8fafc; padding: 0 3px; transform: translateY(-50%); z-index: 150; white-space: nowrap; border: 1px solid #e74c3c; border-radius: 2px;`;
bottomLabel.textContent = totalDepth % 1 === 0 ? totalDepth.toString() : totalDepth.toFixed(1);
depthArea.appendChild(bottomLabel);
const constructionBottomLine = document.createElement('div');
constructionBottomLine.style.cssText = `position: absolute; top: ${finalDepthY}px; left: 0; right: 0; height: 2px; background: #e74c3c; z-index: 25;`;
constructionArea.appendChild(constructionBottomLine);
// Отрисовка открытого ствола
drillingData.forEach((section) => {
const topY = section.depthFrom * scale + topReserve;
const heightY = (section.depthTo - section.depthFrom) * scale;
if (heightY > 1) {
const widthPercent = Math.min(85, Math.max(30, (section.diameter / maxDiameter) * 70));
const leftPos = (100 - widthPercent) / 2;
const element = document.createElement('div');
element.style.cssText = `
position: absolute;
left: ${leftPos}%;
top: ${topY}px;
width: ${widthPercent}%;
height: ${heightY}px;
background: linear-gradient(135deg, #f5cba7, #e8b88a);
border: 1px solid #d35400;
border-radius: 2px;
z-index: 5;
`;
if (heightY > 25) {
const label = document.createElement('div');
label.style.cssText = `
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 10px;
font-weight: bold;
color: #7b4a2e;
white-space: nowrap;
z-index: 6;
text-shadow: 1px 1px 0 rgba(255,255,255,0.5);
`;
label.textContent = `Ø${section.diameter} мм`;
element.appendChild(label);
}
constructionArea.appendChild(element);
}
});
// Отрисовка обсадных колонн
casingData.forEach((section) => {
const topY = section.depthFrom * scale + topReserve;
const heightY = (section.depthTo - section.depthFrom) * scale;
if (heightY > 1) {
const widthPercent = Math.min(85, Math.max(30, (section.diameter / maxDiameter) * 70));
const leftPos = (100 - widthPercent) / 2;
const element = document.createElement('div');
element.style.cssText = `
position: absolute;
left: ${leftPos}%;
top: ${topY}px;
width: ${widthPercent}%;
height: ${heightY}px;
background: repeating-linear-gradient(135deg, rgba(41,128,185,0.4), rgba(41,128,185,0.4) 8px, transparent 8px, transparent 16px);
border: 1.5px solid #1a5276;
border-radius: 2px;
z-index: 5;
`;
if (heightY > 25) {
const label = document.createElement('div');
label.style.cssText = `
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 10px;
font-weight: bold;
color: #1a5276;
white-space: nowrap;
z-index: 6;
text-shadow: 1px 1px 0 rgba(255,255,255,0.5);
`;
label.textContent = `Ø${section.diameter} мм`;
element.appendChild(label);
}
constructionArea.appendChild(element);
}
});
// Принудительная прокрутка
setTimeout(() => {
if (graphicsScrollContainer.scrollHeight > graphicsScrollContainer.clientHeight) {
graphicsScrollContainer.style.overflowY = 'scroll';
} else {
graphicsScrollContainer.style.overflowY = 'auto';
}
}, 100);
}