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); }