Отлично! Давайте внесём эти правки: ## 1. ИСПРАВЛЯЕМ ОТОБРАЖЕНИЕ КАТЕГОРИЙ - разделяем в колонке по своим интервалам: ```javascript // В drawWellStructure, при создании drillCell замените на: const drillCell = document.createElement('div'); drillCell.style.cssText = ` position: absolute; top: ${topY}px; left: 0; width: 100%; height: ${heightY}px; border-bottom: 1px solid #e2e8f0; background: #f8fafc; cursor: pointer; `; // Собираем все категории из интервалов const categoryItems = []; if (geo.intervals && geo.intervals.length > 0) { geo.intervals.forEach(interval => { if (interval.rockCategories && interval.rockCategories !== 'Не указано' && interval.rockCategories !== '') { const cats = interval.rockCategories.split('; '); cats.forEach(cat => { const match = cat.match(/([\d.-]+)-([\d.-]+)\s*-\s*(.+)/); if (match) { categoryItems.push({ from: parseFloat(match[1]), to: parseFloat(match[2]), category: match[3].trim(), intervalFrom: interval.from, intervalTo: interval.to, thickness: interval.thickness }); } else { const simpleMatch = cat.match(/\b([IVX]+)\b/); if (simpleMatch) { categoryItems.push({ category: simpleMatch[1], intervalFrom: interval.from, intervalTo: interval.to }); } } }); } }); } if (categoryItems.length > 0) { // Сортируем по глубине categoryItems.sort((a, b) => (a.from || a.intervalFrom) - (b.from || b.intervalFrom)); // Создаём отдельные блоки для каждой категории const categoriesContainer = document.createElement('div'); categoriesContainer.style.cssText = ` position: relative; width: 100%; height: 100%; `; categoryItems.forEach(catItem => { const catFrom = catItem.from || catItem.intervalFrom; const catTo = catItem.to || catItem.intervalTo; const catTopY = (catFrom - geo.from) * scale; const catHeightY = (catTo - catFrom) * scale; if (catHeightY > 2) { const catBlock = document.createElement('div'); catBlock.style.cssText = ` position: absolute; top: ${catTopY}px; left: 0; width: 100%; height: ${catHeightY}px; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; line-height: 1.3; text-align: center; background: #f8fafc; border-bottom: 1px dotted #e2e8f0; `; catBlock.innerHTML = `${catItem.category}`; categoriesContainer.appendChild(catBlock); } else { // Для очень маленьких интервалов const catBlock = document.createElement('div'); catBlock.style.cssText = ` position: absolute; top: ${catTopY}px; left: 0; width: 100%; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; background: #f8fafc; `; catBlock.innerHTML = `${catItem.category}`; categoriesContainer.appendChild(catBlock); } }); drillCell.appendChild(categoriesContainer); } else { drillCell.innerHTML = ''; } drillCell.addEventListener('click', (e) => { e.stopPropagation(); highlightGeologyBlock(index); if (window.geologyCards && window.geologyCards[index]) { window.geologyCards[index].scrollIntoView({ behavior: 'smooth', block: 'center' }); window.geologyCards[index].click(); } }); drillBody.appendChild(drillCell); ``` ## 2. ИСПРАВЛЯЕМ КОНСТРУКЦИЮ - добавляем пунктирную обводку для обсадки и диаметры: ```javascript // В drawWellConstruction, обновляем отрисовку: // ОТКРЫТЫЙ СТВОЛ - сплошная линия drillingData.forEach((section) => { const topY = section.depthFrom * scale; const heightY = (section.depthTo - section.depthFrom) * scale; if (heightY > 1) { const widthPercent = (section.diameter / maxDiameter) * 60; const leftPos = 50 - (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(90deg, #f5cba7, #e8b88a); border: 1px solid #d35400; border-radius: 2px; `; // Подпись диаметра if (heightY > 20) { const label = document.createElement('div'); label.style.cssText = `position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 9px; font-weight: bold; color: #7b4a2e; white-space: nowrap;`; label.textContent = `Ø${section.diameter} мм`; element.appendChild(label); } constructionBody.appendChild(element); } }); // ОБСАДКА - пунктирная линия casingData.forEach((section) => { const topY = section.depthFrom * scale; const heightY = (section.depthTo - section.depthFrom) * scale; if (heightY > 1) { const widthPercent = (section.diameter / maxDiameter) * 60; const leftPos = 50 - (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.2), rgba(41,128,185,0.2) 8px, transparent 8px, transparent 16px); border: 1px dashed #1a5276; border-radius: 2px; `; // Подпись диаметра обсадки if (heightY > 20) { const label = document.createElement('div'); label.style.cssText = `position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 9px; font-weight: bold; color: #1a5276; white-space: nowrap;`; label.textContent = `Ø${section.diameter} мм`; element.appendChild(label); } constructionBody.appendChild(element); } }); ``` ## 3. ДОБАВЛЯЕМ ПУНКТИРНУЮ ЛИНИЮ ДЛЯ КОЛОНКИ ПРОБ: ```javascript // В drawWellStructure, после отрисовки всех интервалов, добавляем вертикальные линии: // Создаём пунктирные линии для разделения интервалов документирования const assayDivider = document.createElement('div'); assayDivider.style.cssText = ` position: absolute; top: 0; left: ${columnWidth + drillWidth}px; width: 0; height: 100%; border-left: 1px dashed #cbd5e1; pointer-events: none; z-index: 15; `; depthArea.appendChild(assayDivider); // Добавляем горизонтальные пунктирные линии на границах интервалов mergedGeology.forEach((geo) => { const topY = geo.from * scale; const bottomY = geo.to * scale; if (topY >= 0 && topY <= totalHeight) { const line = document.createElement('div'); line.style.cssText = ` position: absolute; top: ${topY}px; left: 60px; right: 0; height: 1px; border-top: 1px dashed #e74c3c; pointer-events: none; z-index: 15; `; depthArea.appendChild(line); } if (bottomY >= 0 && bottomY <= totalHeight && bottomY !== topY) { const line = document.createElement('div'); line.style.cssText = ` position: absolute; top: ${bottomY}px; left: 60px; right: 0; height: 1px; border-top: 1px dashed #e74c3c; pointer-events: none; z-index: 15; `; depthArea.appendChild(line); } }); ``` ## 4. ДОБАВЛЯЕМ ВЕРТИКАЛЬНЫЕ ПУНКТИРНЫЕ ЛИНИИ ДЛЯ ОБЛАСТИ ПРОБ: ```javascript // В drawWellStructure, добавляем сетку для области проб: const assaysGrid = document.createElement('div'); assaysGrid.style.cssText = ` position: absolute; top: 0; left: ${columnWidth + drillWidth}px; width: ${assaysWidth}px; height: 100%; pointer-events: none; z-index: 15; `; // Добавляем вертикальные линии каждые 25px для ориентира for (let x = 25; x < assaysWidth; x += 25) { const vLine = document.createElement('div'); vLine.style.cssText = ` position: absolute; top: 0; left: ${x}px; width: 0; height: 100%; border-left: 1px dotted #e2e8f0; `; assaysGrid.appendChild(vLine); } // Добавляем горизонтальные линии на границах интервалов в области проб mergedGeology.forEach((geo) => { const topY = geo.from * scale; const bottomY = geo.to * scale; if (topY >= 0 && topY <= totalHeight) { const hLine = document.createElement('div'); hLine.style.cssText = ` position: absolute; top: ${topY}px; left: 0; width: 100%; height: 1px; border-top: 1px dotted #e74c3c; `; assaysGrid.appendChild(hLine); } if (bottomY >= 0 && bottomY <= totalHeight && bottomY !== topY) { const hLine = document.createElement('div'); hLine.style.cssText = ` position: absolute; top: ${bottomY}px; left: 0; width: 100%; height: 1px; border-top: 1px dotted #e74c3c; `; assaysGrid.appendChild(hLine); } }); assaysArea.appendChild(assaysGrid); ``` Теперь: - ✅ Категории отображаются отдельными блоками в своих интервалах - ✅ В конструкции отображаются диаметры и для обсадки, и для бурения - ✅ Обсадка имеет пунктирный контур - ✅ Добавлены пунктирные линии для ориентира в колонке проб - ✅ Горизонтальные линии на границах интервалов документирования помогают видеть, куда попадают пробы