Akshaymakhare's picture
I'll help you create a TypeScript project that visualizes the wellbore schematic based on your Excel data. This will display the well path, casing strings, and formations similar to your image.
1319e7f verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wellbore Visualizer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<style>
.casing-gradient {
background: linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%);
}
.formation-line {
stroke-dasharray: 5,5;
}
#vanta-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.1;
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<div id="vanta-bg"></div>
<header class="bg-indigo-900 text-white shadow-lg">
<div class="container mx-auto px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<i data-feather="layers" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">WellboreVisualizer Pro</h1>
</div>
<nav class="hidden md:flex space-x-8">
<a href="#" class="hover:text-indigo-300 transition">Dashboard</a>
<a href="#" class="hover:text-indigo-300 transition">Schematics</a>
<a href="#" class="hover:text-indigo-300 transition">Reports</a>
<a href="#" class="hover:text-indigo-300 transition">Settings</a>
</nav>
<button class="md:hidden focus:outline-none">
<i data-feather="menu" class="w-6 h-6"></i>
</button>
</div>
</div>
</header>
<main class="container mx-auto px-6 py-8">
<div class="flex flex-col lg:flex-row gap-8">
<div class="lg:w-1/4 bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Well Information</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-600">Well Name</label>
<p class="mt-1 text-gray-800">N-11#12</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-600">Field</label>
<p class="mt-1 text-gray-800">Mumbai High North</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-600">Platform</label>
<p class="mt-1 text-gray-800">N-11</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-600">Total Depth</label>
<p class="mt-1 text-gray-800">3,215m MD / 1,416m TVD</p>
</div>
</div>
<div class="mt-8">
<h3 class="text-lg font-medium text-gray-800 mb-3">Casing Strings</h3>
<ul class="space-y-2">
<li class="flex items-center">
<span class="w-6 h-6 rounded-full bg-gray-300 mr-3"></span>
<span>30" Casing (180m)</span>
</li>
<li class="flex items-center">
<span class="w-6 h-6 rounded-full bg-gray-400 mr-3"></span>
<span>20" Casing (308m)</span>
</li>
<li class="flex items-center">
<span class="w-6 h-6 rounded-full bg-gray-500 mr-3"></span>
<span>13.375" Casing (1,676m)</span>
</li>
<li class="flex items-center">
<span class="w-6 h-6 rounded-full bg-gray-600 mr-3"></span>
<span>9.625" Casing (2,920m)</span>
</li>
</ul>
</div>
</div>
<div class="lg:w-3/4">
<div class="bg-white rounded-xl shadow-md p-6">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold text-gray-800">Wellbore Schematic</h2>
<div class="flex space-x-3">
<button class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition flex items-center">
<i data-feather="download" class="w-4 h-4 mr-2"></i> Export
</button>
<button class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition flex items-center">
<i data-feather="share-2" class="w-4 h-4 mr-2"></i> Share
</button>
</div>
</div>
<div class="relative">
<div id="wellbore-schematic" class="w-full h-[600px] border border-gray-200 rounded-lg overflow-hidden"></div>
<div class="absolute bottom-4 right-4 bg-white bg-opacity-90 px-3 py-2 rounded-lg shadow-sm text-sm">
<div class="flex items-center"><span class="w-3 h-3 bg-red-500 rounded-full mr-2"></span> Target Zone</div>
<div class="flex items-center mt-1"><span class="w-3 h-3 bg-amber-700 rounded-full mr-2"></span> Formation Top</div>
</div>
</div>
</div>
<div class="mt-6 bg-white rounded-xl shadow-md p-6">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Drilling Summary</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-indigo-50 p-4 rounded-lg">
<div class="text-indigo-600 font-medium">Surface Section</div>
<div class="text-2xl font-bold mt-2">308m</div>
<div class="text-sm text-gray-500">20" Casing</div>
</div>
<div class="bg-blue-50 p-4 rounded-lg">
<div class="text-blue-600 font-medium">Intermediate Section</div>
<div class="text-2xl font-bold mt-2">1,676m</div>
<div class="text-sm text-gray-500">13⅜" Casing</div>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<div class="text-purple-600 font-medium">Production Section</div>
<div class="text-2xl font-bold mt-2">2,920m</div>
<div class="text-sm text-gray-500">9⅝" Casing</div>
</div>
</div>
</div>
</div>
</div>
</main>
<footer class="bg-gray-800 text-white py-8">
<div class="container mx-auto px-6">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<div class="flex items-center space-x-2">
<i data-feather="layers" class="w-6 h-6"></i>
<span class="text-xl font-bold">WellboreVisualizer Pro</span>
</div>
<p class="mt-2 text-gray-400">Visualizing well data with precision</p>
</div>
<div class="flex space-x-6">
<a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="github"></i></a>
<a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="twitter"></i></a>
<a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="linkedin"></i></a>
</div>
</div>
<div class="border-t border-gray-700 mt-6 pt-6 text-center text-gray-400 text-sm">
<p>© 2023 WellboreVisualizer Pro. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Initialize Vanta.js globe background
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x3f83f8,
backgroundColor: 0xf7fafc
});
// Initialize Feather Icons
feather.replace();
// Sample data for the wellbore schematic
const wellData = {
casings: [
{ name: "30in", diameter: 30, depth: 180, color: "#e2e8f0" },
{ name: "20in", diameter: 20, depth: 308, color: "#cbd5e1" },
{ name: "13.375in", diameter: 13.375, depth: 1676, color: "#94a3b8" },
{ name: "9.625in", diameter: 9.625, depth: 2920, color: "#64748b" }
],
formations: [
{ name: "Top Shale", depth: 365.76, color: "#92400e" },
{ name: "Sand A", depth: 914.4, color: "#b45309" }
],
target: { name: "A2-VII-Target", depth: 1372.25, color: "#dc2626" }
};
// Draw the wellbore schematic using D3.js
document.addEventListener('DOMContentLoaded', function() {
const container = document.getElementById('wellbore-schematic');
const width = container.clientWidth;
const height = container.clientHeight;
const margin = { top: 40, right: 40, bottom: 40, left: 60 };
// Create SVG element
const svg = d3.select('#wellbore-schematic')
.append('svg')
.attr('width', width)
.attr('height', height);
// Create chart group
const chart = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Calculate scales
const chartWidth = width - margin.left - margin.right;
const chartHeight = height - margin.top - margin.bottom;
const maxDepth = 3215;
const yScale = d3.scaleLinear()
.domain([0, maxDepth])
.range([0, chartHeight]);
const diameterScale = d3.scaleLinear()
.domain([0, 30])
.range([0, chartWidth * 0.3]);
// Draw wellbore trajectory
chart.append('line')
.attr('x1', chartWidth / 2)
.attr('y1', 0)
.attr('x2', chartWidth / 2)
.attr('y2', chartHeight)
.attr('stroke', '#4b5563')
.attr('stroke-width', 2);
// Draw casings
wellData.casings.forEach(casing => {
const casingWidth = diameterScale(casing.diameter);
const casingHeight = yScale(casing.depth);
chart.append('rect')
.attr('x', chartWidth / 2 - casingWidth / 2)
.attr('y', 0)
.attr('width', casingWidth)
.attr('height', casingHeight)
.attr('fill', casing.color)
.attr('stroke', '#4b5563')
.attr('stroke-width', 1);
// Add casing label
chart.append('text')
.attr('x', chartWidth / 2 + casingWidth / 2 + 10)
.attr('y', casingHeight / 2)
.attr('dy', '0.35em')
.text(`${casing.diameter}" ${casing.name}`)
.style('font-size', '10px')
.style('fill', '#1f2937');
});
// Draw formations
wellData.formations.forEach(formation => {
const y = yScale(formation.depth);
chart.append('line')
.attr('x1', chartWidth / 2 - diameterScale(15))
.attr('y1', y)
.attr('x2', chartWidth / 2 + diameterScale(15))
.attr('y2', y)
.attr('stroke', formation.color)
.attr('stroke-width', 2)
.attr('stroke-dasharray', '5,5');
chart.append('text')
.attr('x', chartWidth / 2 + diameterScale(15) + 10)
.attr('y', y)
.attr('dy', '0.35em')
.text(`${formation.name} (${Math.round(formation.depth)}m)`)
.style('font-size', '10px')
.style('fill', formation.color);
});
// Draw target
const targetY = yScale(wellData.target.depth);
chart.append('circle')
.attr('cx', chartWidth / 2)
.attr('cy', targetY)
.attr('r', 6)
.attr('fill', wellData.target.color);
chart.append('text')
.attr('x', chartWidth / 2 + 15)
.attr('y', targetY)
.attr('dy', '0.35em')
.text(wellData.target.name)
.style('font-size', '10px')
.style('fill', wellData.target.color);
// Add depth scale
const yAxis = d3.axisLeft(yScale).ticks(10).tickFormat(d => `${d}m`);
chart.append('g')
.attr('class', 'axis')
.call(yAxis)
.select('.domain')
.attr('stroke', '#9ca3af');
});
</script>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>feather.replace();</script>
</body>
</html>