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 | <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> | |