Отзывы и предложения к софту от AleXStam
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поговорим о...
s
конвертер
Прикрепления:
konverter.zip (8.1 Kb)
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, maximum-scale=2.0">
<title>Геологическая колонка · ГОСТ · Сплошной столбик v3</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
background: #dee2e6;
font-family: 'Inter', 'Segoe UI', 'Roboto', system-ui, -apple-system, sans-serif;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
padding: 2rem 1rem;
margin: 0;
}

.main-frame {
max-width: 1020px;
width: 100%;
background: #ffffff;
border-radius: 3px;
box-shadow: 0 6px 22px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.05);
padding: 1.4rem 1.6rem 1.8rem;
border: 1px solid #b0bec5;
}

.title-section {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 1.2rem;
border-bottom: 2px solid #1e293b;
padding-bottom: 0.5rem;
}

.title-section h2 {
font-weight: 600;
font-size: 1.5rem;
letter-spacing: 0.02em;
color: #0f172a;
text-transform: uppercase;
margin: 0;
}

.title-section .well-id {
font-weight: 500;
font-size: 0.8rem;
color: #334155;
background: #f1f5f9;
padding: 0.2rem 1rem;
border-radius: 16px;
}

/* ----- компоновка: шкала + колонка + инфо ----- */
.column-layout {
display: flex;
gap: 0;
border: 1px solid #90a4ae;
background: #ffffff;
position: relative;
min-height: 640px;
user-select: none;
}

/* левая шкала: глубины + номера документирования */
.depth-scale-area {
width: 80px;
min-width: 80px;
background: #f8fafc;
border-right: 1px solid #cbd5e1;
display: flex;
flex-direction: column;
position: relative;
font-size: 0.7rem;
color: #1e293b;
}

.depth-scale-header {
height: 40px;
background: #e2e8f0;
border-bottom: 1px solid #94a3b8;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: #0f172a;
}

.depth-scale-body {
flex: 1;
position: relative;
background: #f8fafc;
}

.tick-mark {
position: absolute;
left: 0;
width: 100%;
display: flex;
align-items: center;
height: 0;
pointer-events: none;
z-index: 1;
}

.tick-line {
position: absolute;
left: 52px;
right: 0;
height: 1px;
background: #b0bec5;
}

.tick-label {
position: absolute;
left: 6px;
font-weight: 600;
font-size: 0.68rem;
color: #1e293b;
background: #f8fafc;
padding: 0 2px;
transform: translateY(-50%);
}

.doc-number {
position: absolute;
left: 38px;
font-weight: 800;
font-size: 0.75rem;
color: #0f3b5e;
background: transparent;
transform: translateY(-50%);
z-index: 3;
letter-spacing: 0.3px;
text-shadow: 0 0 2px white;
pointer-events: none;
}

/* центральная колонка */
.core-column {
width: 110px;
min-width: 110px;
background: #ffffff;
border-right: 1px solid #cbd5e1;
display: flex;
flex-direction: column;
position: relative;
}

.core-header {
height: 40px;
background: #e2e8f0;
border-bottom: 1px solid #94a3b8;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: #0f172a;
}

.core-body {
flex: 1;
position: relative;
background: #ffffff;
}

.litho-block {
position: absolute;
left: 8px;
right: 8px;
border-radius: 3px;
border: 1px solid rgba(0, 0, 0, 0.25);
cursor: pointer;
transition: all 0.15s ease;
display: flex;
align-items: center;
justify-content: center;
}

.litho-block:hover {
filter: brightness(0.94);
border-color: #1e40af;
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.25);
z-index: 5;
}

.litho-block.active-layer {
border: 2px solid #b91c1c !important;
box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.25);
filter: brightness(0.96);
z-index: 6;
}

.age-on-core {
font-weight: 700;
font-size: 0.7rem;
color: #0f172a;
background: rgba(255, 255, 255, 0.8);
padding: 2px 6px;
border-radius: 3px;
letter-spacing: 0.4px;
text-align: center;
pointer-events: none;
line-height: 1.2;
}

/* правая панель */
.info-panel {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
background: #ffffff;
}

.info-header-row {
display: flex;
height: 40px;
background: #e2e8f0;
border-bottom: 1px solid #94a3b8;
font-weight: 700;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: #0f172a;
}

.info-header-row > div {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-right: 1px solid #cbd5e1;
padding: 0 0.2rem;
}
.info-header-row > div:last-child {
border-right: none;
}

.info-body {
flex: 1;
position: relative;
background: #ffffff;
}

.info-drill-col {
width: 55px;
min-width: 55px;
}
.info-sample-col {
width: 155px;
min-width: 155px;
}
.info-desc-col {
flex: 1;
}

.info-row-group {
position: absolute;
left: 0;
right: 0;
display: flex;
border-bottom: 1px solid #e2e8f0;
transition: background 0.2s;
}

.info-row-group.highlight-desc {
background: #fff7ed;
border-left: 3px solid #c2410c;
z-index: 4;
}

.info-row-group > div {
display: flex;
align-items: center;
padding: 0.15rem 0.3rem;
font-size: 0.68rem;
border-right: 1px solid #e2e8f0;
color: #1e293b;
line-height: 1.3;
}
.info-row-group > div:last-child {
border-right: none;
}

.drill-cell-info {
justify-content: center;
font-weight: 700;
font-size: 0.78rem;
background: #f1f5f9;
}

/* Пробы – гравитационное размещение без наложения */
.sample-cell-info {
position: relative;
background: #ffffff;
overflow: visible;
}

.sample-marker {
position: absolute;
left: 4px;
right: 4px;
font-size: 0.58rem;
font-weight: 700;
padding: 2px 4px;
border-radius: 3px;
white-space: nowrap;
letter-spacing: 0.2px;
z-index: 5;
background: #f0fdfa;
border-left: 3px solid #0d9488;
color: #115e59;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
overflow: hidden;
text-overflow: ellipsis;
}

.sample-marker.interval {
background: #fdf2f8;
border-left-color: #b45389;
color: #831843;
}

.desc-cell-info {
font-size: 0.65rem;
line-height: 1.4;
align-items: flex-start;
color: #334155;
background: #ffffff;
cursor: pointer;
padding: 0.3rem 0.4rem;
transition: background 0.15s;
}

.desc-cell-info:hover {
background: #f1f5f9;
}

.desc-cell-info.active-desc {
background: #ffedd5;
font-weight: 500;
}

/* краповые узоры */
.pattern-sand {
background: repeating-linear-gradient(45deg, #c9a87c 0px, #c9a87c 2px, #f5e6d3 2px, #f5e6d3 7px);
}
.pattern-clay {
background: repeating-linear-gradient(0deg, #8b8b8b 0px, #8b8b8b 1.5px, #d4cfc4 1.5px, #d4cfc4 5px);
}
.pattern-limestone {
background: repeating-linear-gradient(90deg, #a0a0a0 0px, #a0a0a0 1px, #e8e8e8 1px, #e8e8e8 6px);
}
.pattern-silt {
background: radial-gradient(circle, #9c9c8a 1.2px, transparent 1.2px);
background-size: 7px 7px;
background-color: #ece7d5;
}
.pattern-granite {
background: repeating-linear-gradient(135deg, #b07040 0px, #b07040 1.8px, #e2c9a8 1.8px, #e2c9a8 7px);
}

.footer-note {
margin-top: 0.9rem;
font-size: 0.65rem;
color: #475569;
display: flex;
gap: 2rem;
background: #f9fafb;
padding: 0.4rem 0.8rem;
border-radius: 3px;
}
</style>
</head>
<body>
<div class="main-frame">
<div class="title-section">
<h2>🪨 Геологическая колонка</h2>
<span class="well-id">Скв. 42-К · ГОСТ 2.857-75</span>
</div>

<div class="column-layout" id="columnLayout">
<!-- Левая шкала -->
<div class="depth-scale-area">
<div class="depth-scale-header">Глубина, м</div>
<div class="depth-scale-body" id="depthScaleBody"></div>
</div>

<!-- Центральная колонка -->
<div class="core-column">
<div class="core-header">Колонка</div>
<div class="core-body" id="coreBody"></div>
</div>

<!-- Правая панель -->
<div class="info-panel">
<div class="info-header-row">
<div class="info-drill-col">Кат. бур.</div>
<div class="info-sample-col">Пробы</div>
<div class="info-desc-col">Описание пород</div>
</div>
<div class="info-body" id="infoBody"></div>
</div>
</div>

<div class="footer-note">
<span>🔹 Клик по слою колонки → подсветка описания</span>
<span>🔸 Клик по описанию → подсветка слоя в колонке</span>
<span>📐 Пробы распределены без наложения</span>
</div>
</div>

<script>
(function() {
// ----- ДАННЫЕ -----
const totalDepth = 16.0;
const pxPerMeter = 38;

const layers = [
{ id: 0, depthTop: 0.0, depthBottom: 2.8, litho: 'sand', age: 'Q', drillCat: 'I', desc: 'Песок среднезернистый, желтовато-серый, рыхлый, с гравием.' },
{ id: 1, depthTop: 2.8, depthBottom: 6.0, litho: 'clay', age: 'N', drillCat: 'II', desc: 'Глина плотная, коричневая, пластичная, с прослоями алеврита.' },
{ id: 2, depthTop: 6.0, depthBottom: 9.2, litho: 'limestone', age: 'K', drillCat: 'III', desc: 'Известняк серый, трещиноватый, кальцитовые прожилки.' },
{ id: 3, depthTop: 9.2, depthBottom: 12.5, litho: 'silt', age: 'J', drillCat: 'III', desc: 'Алевролит темно-серый, слоистый, слабо сцементированный.' },
{ id: 4, depthTop: 12.5, depthBottom: 16.0, litho: 'granite', age: 'PZ', drillCat: 'IV', desc: 'Гранит биотитовый, розовато-серый, крепкий, трещиноватый.' }
];

const pointSamples = [
{ depth: 1.3, label: 'П-1' },
{ depth: 4.5, label: 'П-2' },
{ depth: 7.8, label: 'П-3' },
{ depth: 10.9, label: 'П-4' },
{ depth: 14.0, label: 'П-5' }
];

const intervalSamples = [
{ top: 0.6, bottom: 2.4, label: 'Инт-А' },
{ top: 3.0, bottom: 5.8, label: 'Инт-Б' },
{ top: 6.2, bottom: 8.9, label: 'Инт-В' },
{ top: 9.1, bottom: 12.2, label: 'Инт-Г' },
{ top: 12.6, bottom: 15.1, label: 'Инт-Д' }
];

// Интервалы документирования (только номера)
const docIntervals = [
{ top: 0.0, bottom: 3.2, number: '1' },
{ top: 3.2, bottom: 7.0, number: '2' },
{ top: 7.0, bottom: 11.0, number: '3' },
{ top: 11.0, bottom: 16.0, number: '4' }
];

function getLithoClass(litho) {
const map = {
'sand': 'pattern-sand',
'clay': 'pattern-clay',
'limestone': 'pattern-limestone',
'silt': 'pattern-silt',
'granite': 'pattern-granite'
};
return map[litho] || 'pattern-sand';
}

function getIntervalSamplesForLayer(top, bottom) {
return intervalSamples.filter(s => s.top < bottom && s.bottom > top);
}

function getPointSamplesForLayer(top, bottom) {
return pointSamples.filter(s => s.depth >= top && s.depth <= bottom);
}

// ---- Глобальное состояние подсветки ----
let activeLayerId = null;

const coreBody = document.getElementById('coreBody');
const infoBody = document.getElementById('infoBody');
const depthScaleBody = document.getElementById('depthScaleBody');

const totalHeight = totalDepth * pxPerMeter;
coreBody.style.height = totalHeight + 'px';
infoBody.style.height = totalHeight + 'px';
depthScaleBody.style.height = totalHeight + 'px';

// ---- Левая шкала ----
function renderDepthScale() {
depthScaleBody.innerHTML = '';
for (let d = 0; d <= totalDepth; d += 0.5) {
const yPos = d * pxPerMeter;
const tick = document.createElement('div');
tick.className = 'tick-mark';
tick.style.top = yPos + 'px';
tick.innerHTML = '<div class="tick-line"></div><span class="tick-label">' + d.toFixed(1) + '</span>';
depthScaleBody.appendChild(tick);
}
docIntervals.forEach(doc => {
const midY = (doc.top + doc.bottom) / 2 * pxPerMeter;
const numDiv = document.createElement('div');
numDiv.className = 'doc-number';
numDiv.style.top = midY + 'px';
numDiv.textContent = doc.number;
depthScaleBody.appendChild(numDiv);
});
}

// ---- Центральная колонка ----
function renderCoreColumn() {
coreBody.innerHTML = '';
layers.forEach(layer => {
const topPx = layer.depthTop * pxPerMeter;
const heightPx = (layer.depthBottom - layer.depthTop) * pxPerMeter;
const block = document.createElement('div');
block.className = 'litho-block ' + getLithoClass(layer.litho);
block.style.top = topPx + 'px';
block.style.height = heightPx + 'px';
block.dataset.layerId = layer.id;

if (activeLayerId === layer.id) {
block.classList.add('active-layer');
}

const ageSpan = document.createElement('span');
ageSpan.className = 'age-on-core';
ageSpan.textContent = layer.age;
block.appendChild(ageSpan);

block.addEventListener('click', (e) => {
e.stopPropagation();
setActiveLayer(layer.id);
});

coreBody.appendChild(block);
});
}

// ---- Правая панель ----
function renderInfoPanel() {
infoBody.innerHTML = '';
layers.forEach(layer => {
const topPx = layer.depthTop * pxPerMeter;
const heightPx = (layer.depthBottom - layer.depthTop) * pxPerMeter;

const row = document.createElement('div');
row.className = 'info-row-group';
row.style.top = topPx + 'px';
row.style.height = heightPx + 'px';
row.dataset.layerId = layer.id;

if (activeLayerId === layer.id) {
row.classList.add('highlight-desc');
}

// Категория
const drillDiv = document.createElement('div');
drillDiv.className = 'info-drill-col drill-cell-info';
drillDiv.textContent = layer.drillCat;

// Пробы (гравитационное размещение)
const sampleDiv = document.createElement('div');
sampleDiv.className = 'info-sample-col sample-cell-info';
sampleDiv.style.position = 'relative';

const pointSamps = getPointSamplesForLayer(layer.depthTop, layer.depthBottom);
const intervalSamps = getIntervalSamplesForLayer(layer.depthTop, layer.depthBottom);

const allSamples = [];
pointSamps.forEach(p => allSamples.push({ type: 'point', depth: p.depth, label: p.label, top: p.depth, bottom: p.depth }));
intervalSamps.forEach(s => allSamples.push({ type: 'interval', depth: (s.top + s.bottom)/2, label: s.label, top: s.top, bottom: s.bottom }));

// Сортируем по глубине
allSamples.sort((a, b) => a.depth - b.depth);

// Распределяем вертикально без наложения внутри ячейки
const cellHeight = heightPx;
const markerHeight = 18; // примерная высота маркера
const count = allSamples.length;

if (count > 0) {
const spacing = Math.min(markerHeight + 2, (cellHeight - 4) / count);
allSamples.forEach((s, idx) => {
const marker = document.createElement('div');
marker.className = 'sample-marker' + (s.type === 'interval' ? ' interval' : '');
const depthStr = s.type === 'point' ? s.top.toFixed(1) + 'м' : s.top.toFixed(1) + '–' + s.bottom.toFixed(1) + 'м';
marker.textContent = s.label + ' ' + depthStr;
marker.style.top = (4 + idx * spacing) + 'px';
sampleDiv.appendChild(marker);
});
} else {
sampleDiv.textContent = '—';
sampleDiv.style.color = '#9ca3af';
sampleDiv.style.justifyContent = 'center';
sampleDiv.style.alignItems = 'center';
}

// Описание
const descDiv = document.createElement('div');
descDiv.className = 'info-desc-col desc-cell-info';
descDiv.textContent = layer.desc;
if (activeLayerId === layer.id) {
descDiv.classList.add('active-desc');
}
descDiv.addEventListener('click', (e) => {
e.stopPropagation();
setActiveLayer(layer.id);
});

row.appendChild(drillDiv);
row.appendChild(sampleDiv);
row.appendChild(descDiv);
infoBody.appendChild(row);
});
}

// Установка активного слоя и перерисовка
function setActiveLayer(id) {
if (activeLayerId === id) {
activeLayerId = null;
} else {
activeLayerId = id;
}
renderCoreColumn();
renderInfoPanel();
}

// Первичная отрисовка
renderDepthScale();
renderCoreColumn();
renderInfoPanel();
})();
</script>
</body>
</html>
jjjjj
Прикрепления:
222
Прикрепления:
8601631.txt (36.2 Kb)
555
Прикрепления:
7756013.txt (33.5 Kb)
3333
Прикрепления:
4004588.txt (34.7 Kb)
5555
555
Прикрепления:
5954440.txt (31.6 Kb)
44444
Прикрепления:
0533593.txt (21.7 Kb)
333
Прикрепления:
2466958.txt (22.8 Kb)
3333
Прикрепления:
3970503.txt (12.5 Kb)
3333
Прикрепления:
4469431.txt (24.3 Kb)
вапапва
Прикрепления:
5913770.txt (16.1 Kb)
sdfsd
Прикрепления:
9978511.txt (14.7 Kb)
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поиск:
Новый ответ
Имя:
Текст сообщения: