Отлично! Давайте внесём эти правки:
## 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);
```
Теперь:
- ✅ Категории отображаются отдельными блоками в своих интервалах
- ✅ В конструкции отображаются диаметры и для обсадки, и для бурения
- ✅ Обсадка имеет пунктирный контур
- ✅ Добавлены пунктирные линии для ориентира в колонке проб
- ✅ Горизонтальные линии на границах интервалов документирования помогают видеть, куда попадают пробы