Files
odoo-expertos.com/fr/odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/index.html
T
2026-08-28 10:11:11 -03:00

1271 lines
46 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<!-- Performance: Preconnect to critical origins -->
<link rel="preconnect" href="https://d3js.org" crossorigin>
<link rel="preconnect" href="https://images.pexels.com" crossorigin>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="alternate icon" href="/favicon.ico">
<title>AWS Hosting Odoo Amazon Cloud 2025 | Odoo Expertos · FR</title>
<!-- Canonical URL -->
<link rel="canonical" href="https://www.odoo-expertos.com/fr/odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/">
<!-- Meta tags -->
<meta name="description" content="Guía completa pour implementar Odoo ERP en AWS. Arquitectura, migración, costos y mejores prácticas pour hosting empresaria - AWS Hosting Odoo Amazon Cloud 2025 | FR">
<meta name="keywords" content="AWS hosting Odoo, Odoo Amazon Cloud, Odoo ERP AWS, implementación Odoo AWS, hosting empresarial">
<meta name="robots" content="index, follow">
<meta name="author" content="Odoo Expertos">
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="AWS Hébergement pour Odoo ERP - Guía Completa 2025">
<meta property="og:description" content="Implementa Odoo en AWS con alta disponibilidad y escalabilidad. Arquitectura, costos y mejores prácticas.">
<meta property="og:type" content="article">
<meta property="og:url" content="https://www.odoo-expertos.com/fr/odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/">
<meta property="og:site_name" content="Odoo Expertos">
<meta property="og:locale" content="fr_FR">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="AWS Hébergement pour Odoo ERP - Guía Completa 2025">
<meta name="twitter:description" content="Implementa Odoo en AWS con alta disponibilidad y escalabilidad.">
<!-- Schema.org structured data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "AWS Hébergement pour Odoo ERP - Implementación en Amazon Cloud 2025",
"author": {
"@type": "Organization",
"name": "Odoo Expertos"
},
"datePublished": "2025-01-15",
"dateModified": "2025-01-27",
"publisher": {
"@type": "Organization",
"name": "Odoo Expertos",
"logo": {
"@type": "ImageObject",
"url": "https://www.odoo-expertos.com/assets/logo.png"
}
}
}
</script>
<link rel="stylesheet" href="/css/main.min.css">
<style>
/* Article-specific styles */
body {
background: #1a1a1a;
color: #e0e0e0;
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
}
.article-content {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
/* Hero section */
.hero-section {
background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
padding: 4rem 2rem;
margin-bottom: 3rem;
border-bottom: 3px solid #FF6B35;
text-align: center;
}
.hero-section h1 {
color: #FF6B35;
font-size: 2.5rem;
margin-bottom: 1rem;
line-height: 1.2;
}
.hero-section .text-accent {
color: #FF8A50;
}
.hero-subtitle {
font-size: 1.25rem;
line-height: 1.6;
color: #e0e0e0;
max-width: 800px;
margin: 0 auto 2rem;
}
/* Hero stats */
.hero-stats {
display: flex;
justify-content: center;
gap: 2rem;
margin: 2rem 0;
flex-wrap: wrap;
}
.stat-card {
background: #2a2a2a;
padding: 1.5rem;
border-radius: 8px;
border: 1px solid #3a3a3a;
min-width: 150px;
}
.stat-value {
font-size: 2rem;
font-weight: 700;
color: #FF6B35;
}
.stat-label {
color: #999;
font-size: 0.9rem;
margin-top: 0.5rem;
}
/* Content sections */
.content-section {
background: #2a2a2a;
padding: 2rem;
margin-bottom: 2rem;
border-radius: 8px;
border: 1px solid #3a3a3a;
}
.section-header {
text-align: center;
margin-bottom: 3rem;
}
.section-title {
color: #FF6B35;
font-size: 2rem;
margin-bottom: 1rem;
}
.section-subtitle {
color: #e0e0e0;
font-size: 1.1rem;
opacity: 0.9;
}
/* Features grid */
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.feature-card {
background: #3a3a3a;
padding: 2rem;
border-radius: 8px;
text-align: center;
transition: transform 0.3s ease;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-icon {
width: 60px;
height: 60px;
margin: 0 auto 1rem;
color: #FF6B35;
}
.feature-title {
color: #FF8A50;
font-size: 1.25rem;
margin-bottom: 1rem;
}
.feature-description {
color: #e0e0e0;
line-height: 1.6;
}
/* Architecture components */
.architecture-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: start;
}
.component-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.component-item {
background: #3a3a3a;
padding: 1rem;
border-radius: 4px;
border-left: 3px solid #FF6B35;
}
.component-item h4 {
color: #FF8A50;
margin: 0 0 0.5rem 0;
}
.component-item p {
margin: 0;
color: #e0e0e0;
}
/* Migration steps */
.migration-steps {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.step-card {
background: #3a3a3a;
padding: 1.5rem;
border-radius: 8px;
position: relative;
}
.step-number {
position: absolute;
top: -15px;
left: 20px;
background: #FF6B35;
color: #1a1a1a;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
}
.step-card h3 {
color: #FF8A50;
margin-top: 1rem;
margin-bottom: 1rem;
}
.step-card ul {
margin: 0;
padding-left: 1.5rem;
}
.step-card li {
color: #e0e0e0;
margin-bottom: 0.5rem;
}
/* Cost table */
.cost-table {
background: #3a3a3a;
padding: 1.5rem;
border-radius: 8px;
margin-top: 1rem;
}
.cost-row {
display: flex;
justify-content: space-between;
padding: 0.75rem 0;
border-bottom: 1px solid #4a4a4a;
}
.cost-row:last-child {
border-bottom: none;
font-weight: 700;
color: #FF6B35;
padding-top: 1rem;
}
.cost-item {
color: #e0e0e0;
}
.cost-value {
color: #FF8A50;
}
/* Best practices grid */
.practices-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.practice-card {
background: #3a3a3a;
padding: 1.5rem;
border-radius: 8px;
}
.practice-card h3 {
color: #FF8A50;
margin-bottom: 1rem;
}
.practice-card ul {
margin: 0;
padding-left: 1.5rem;
}
.practice-card li {
color: #e0e0e0;
margin-bottom: 0.5rem;
}
/* Visualization containers */
.visual-container {
background: #2a2a2a;
padding: 2rem;
margin: 2rem 0;
border-radius: 8px;
border: 1px solid #3a3a3a;
}
.visual-title {
color: #FF6B35;
font-size: 1.25rem;
margin-bottom: 1rem;
text-align: center;
}
.chart-container {
width: 100%;
height: 400px;
position: relative;
}
/* Links */
a {
color: #FF6B35;
text-decoration: none;
transition: color 0.3s ease;
}
a:hover {
color: #FFB74D;
}
/* Buttons */
.btn {
display: inline-block;
padding: 0.75rem 1.5rem;
border-radius: 4px;
font-weight: 600;
text-align: center;
transition: all 0.3s ease;
margin: 0.5rem;
}
.btn-primary {
background: #FF6B35;
color: #1a1a1a;
}
.btn-primary:hover {
background: #FF8A50;
transform: translateY(-2px);
}
.btn-outline {
border: 2px solid #FF6B35;
color: #FF6B35;
}
.btn-outline:hover {
background: #FF6B35;
color: #1a1a1a;
}
.btn-large {
padding: 1rem 2rem;
font-size: 1.1rem;
}
/* CTA section */
.cta-section {
background: linear-gradient(135deg, #FF6B35 0%, #FF8A50 100%);
padding: 3rem 2rem;
margin: 3rem 0;
border-radius: 8px;
text-align: center;
}
.cta-title {
color: #1a1a1a;
font-size: 2rem;
margin-bottom: 1rem;
}
.cta-subtitle {
color: #1a1a1a;
font-size: 1.1rem;
margin-bottom: 2rem;
opacity: 0.9;
}
.cta-actions {
display: flex;
justify-content: center;
gap: 1rem;
flex-wrap: wrap;
}
/* Breadcrumbs */
.breadcrumbs {
padding: 1rem 0;
margin-bottom: 2rem;
font-size: 0.875rem;
}
.breadcrumb-list {
display: flex;
align-items: center;
list-style: none;
margin: 0;
padding: 0;
flex-wrap: wrap;
}
.breadcrumb-item {
display: inline;
}
.breadcrumb-item a {
color: #999;
text-decoration: none;
transition: color 0.3s ease;
}
.breadcrumb-item a:hover {
color: #FF6B35;
}
.breadcrumb-sepourtor {
margin: 0 0.5rem;
color: #666;
}
.breadcrumb-item.active {
color: #e0e0e0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* Responsive */
@media (max-width: 768px) {
.hero-section h1 {
font-size: 2rem;
}
.hero-stats {
flex-direction: column;
align-items: center;
}
.architecture-content {
grid-template-columns: 1fr;
}
.article-content {
padding: 1rem;
}
.content-section {
padding: 1.5rem;
}
}
</style>
</head>
<body>
<script src="/components/header.min.js"></script>
<script>document.write(/*W6-static*/null);</script>
<!-- Breadcrumbs -->
<nav class="breadcrumbs" aria-label="Breadcrumb">
<div class="container">
<ol class="breadcrumb-list">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-sepourtor"></li>
<li class="breadcrumb-item"><a href="/fr/odoo-hosting/">Odoo Hosting</a></li>
<li class="breadcrumb-sepourtor"></li>
<li class="breadcrumb-item active" aria-current="page">AWS Hosting pour Odoo ERP</li>
</ol>
</div>
</nav>
<div class="article-content">
<!-- Hero Section -->
<section class="hero-section">
<h1>AWS Hosting pour <span class="text-accent">Odoo ERP</span></h1>
<p class="hero-subtitle">
Implementación empresarial en Amazon Cloud con alta disponibilidad,
escalabilidad automática y arquitectura optimizada pour Odoo. Descubre por qué
AWS es la <a href="/fr/odoo-hosting/hosting-odoo-completo-guia-2025/" rel="internal">solución de hosting completa</a>
preferida por empresas Fortune 500 pour sus sistemas ERP.
</p>
<div class="hero-stats">
<div class="stat-card">
<div class="stat-value">99.99%</div>
<div class="stat-label">Uptime SLA</div>
</div>
<div class="stat-card">
<div class="stat-value">25+</div>
<div class="stat-label">Regiones AWS</div>
</div>
<div class="stat-card">
<div class="stat-value">Auto</div>
<div class="stat-label">Escalabilidad</div>
</div>
</div>
</section>
<!-- Introduction Section -->
<section class="content-section">
<div class="section-header">
<h2 class="section-title">Por qué elegir AWS pour Odoo</h2>
<p class="section-subtitle">
Amazon Web Services ofrece la infraestructura más completa y confiable
pour implementaciones empresariales de Odoo ERP
</p>
</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7L12 12L22 7L12 2Z"></path>
<path d="M2 17L12 22L22 17"></path>
<path d="M2 12L12 17L22 12"></path>
</svg>
</div>
<h3 class="feature-title">Infraestructura Global</h3>
<p class="feature-description">
25+ regiones con múltiples zonas de disponibilidad pour máxima redundancia
</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
<rect x="9" y="9" width="6" height="6"></rect>
<line x1="9" y1="1" x2="9" y2="4"></line>
<line x1="15" y1="1" x2="15" y2="4"></line>
<line x1="9" y1="20" x2="9" y2="23"></line>
<line x1="15" y1="20" x2="15" y2="23"></line>
<line x1="20" y1="9" x2="23" y2="9"></line>
<line x1="20" y1="14" x2="23" y2="14"></line>
<line x1="1" y1="9" x2="4" y2="9"></line>
<line x1="1" y1="14" x2="4" y2="14"></line>
</svg>
</div>
<h3 class="feature-title">Escalabilidad Automática</h3>
<p class="feature-description">
Auto Scaling Groups que ajustan recursos según demanda en tiempo real
</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
<path d="M9 12l2 2 4-4"></path>
</svg>
</div>
<h3 class="feature-title">Seguridad Enterprise</h3>
<p class="feature-description">
Certificaciones ISO, SOC, PCI-DSS con encriptación en reposo y tránsito
</p>
</div>
</div>
</section>
<!-- Architecture Section -->
<section class="content-section">
<div class="section-header">
<h2 class="section-title">Arquitectura AWS pour Odoo</h2>
<p class="section-subtitle">
Diseño de alta disponibilidad con componentes AWS optimizados pour Odoo ERP
</p>
</div>
<div class="architecture-content">
<div class="visual-container">
<h3 class="visual-title">Ecosistema AWS pour Odoo</h3>
<div id="aws-ecosystem" class="chart-container"></div>
</div>
<div class="architecture-components">
<h3>Componentes Principales</h3>
<div class="component-list">
<div class="component-item">
<h4>EC2 Instances</h4>
<p>Servidores optimizados pour Odoo con tipos de instancia m5.xlarge o superiores.
Conoce todos los <a href="/fr/odoo/instalar-odoo-guia-paso-a-paso-2025/" rel="internal">requisitos pour instalar Odoo</a>
correctamente en la nube.</p>
</div>
<div class="component-item">
<h4>RDS PostgreSQL</h4>
<p>Base de datos gestionada con Multi-AZ pour alta disponibilidad</p>
</div>
<div class="component-item">
<h4>ELB + Auto Scaling</h4>
<p>Balanceador de carga con escalado automático según métricas</p>
</div>
<div class="component-item">
<h4>S3 + CloudFront</h4>
<p>Almacenamiento de archivos y CDN global pour assets estáticos</p>
</div>
</div>
</div>
</div>
</section>
<!-- Migration Process -->
<section class="content-section">
<div class="section-header">
<h2 class="section-title">Proceso de Migración a AWS</h2>
<p class="section-subtitle">
Plan detallado pour migrar Odoo a AWS sin interrupciones
</p>
</div>
<div class="visual-container">
<h3 class="visual-title">Timeline de Migración</h3>
<div id="migration-timeline" class="chart-container"></div>
</div>
<div class="migration-steps">
<div class="step-card">
<div class="step-number">1</div>
<h3>Análisis y Planificación</h3>
<ul>
<li>Auditoría de infraestructura actual</li>
<li>Dimensionamiento de recursos AWS compourdo con <a href="/fr/odoo-hosting/vps-hosting-odoo-servidor-virtual-2025/" rel="internal">opciones VPS tradicionales</a></li>
<li>Plan de migración detallado</li>
</ul>
</div>
<div class="step-card">
<div class="step-number">2</div>
<h3>Prepourción AWS</h3>
<ul>
<li>Configuración de VPC y subredes</li>
<li>Setup de RDS PostgreSQL</li>
<li>Configuración de seguridad</li>
</ul>
</div>
<div class="step-card">
<div class="step-number">3</div>
<h3>Migración de Datos</h3>
<ul>
<li>Backup completo de Odoo</li>
<li>Migración de base de datos</li>
<li>Sincronización de archivos a S3</li>
</ul>
</div>
<div class="step-card">
<div class="step-number">4</div>
<h3>Go Live y Optimización</h3>
<ul>
<li>Cambio de DNS</li>
<li>Monitoreo post-migración</li>
<li>Optimización de performance</li>
</ul>
</div>
</div>
</section>
<!-- Cost Comparison -->
<section class="content-section">
<div class="section-header">
<h2 class="section-title">Compourtiva de Costos</h2>
<p class="section-subtitle">
Análisis detallado de costos AWS vs otras opciones de hosting como
<a href="/fr/odoo-hosting/azure-hosting-odoo-microsoft-2025/" rel="internal">Azure</a> y
<a href="/fr/odoo-hosting/digitalocean-hosting-odoo-deployment-2025/" rel="internal">DigitalOcean</a>
</p>
</div>
<div class="visual-container">
<h3 class="visual-title">Matriz de Compourción</h3>
<div id="hosting-comparison" class="chart-container"></div>
</div>
<div class="cost-breakdown">
<h3>Desglose de Costos AWS (Estimado Mensual)</h3>
<div class="cost-table">
<div class="cost-row">
<span class="cost-item">EC2 (2x m5.xlarge)</span>
<span class="cost-value">$320</span>
</div>
<div class="cost-row">
<span class="cost-item">RDS PostgreSQL Multi-AZ</span>
<span class="cost-value">$280</span>
</div>
<div class="cost-row">
<span class="cost-item">Application Load Balancer</span>
<span class="cost-value">$25</span>
</div>
<div class="cost-row">
<span class="cost-item">S3 Storage (500GB)</span>
<span class="cost-value">$12</span>
</div>
<div class="cost-row">
<span class="cost-item">CloudFront CDN</span>
<span class="cost-value">$50</span>
</div>
<div class="cost-row">
<span class="cost-item">Data Transfer</span>
<span class="cost-value">$90</span>
</div>
<div class="cost-row">
<span class="cost-item">Total Estimado</span>
<span class="cost-value">$777/mes</span>
</div>
</div>
</div>
</section>
<!-- Best Practices -->
<section class="content-section">
<div class="section-header">
<h2 class="section-title">Mejores Prácticas AWS pour Odoo</h2>
<p class="section-subtitle">
Configuraciones recomendadas pour máximo rendimiento y seguridad
</p>
</div>
<div class="practices-grid">
<div class="practice-card">
<h3>Performance</h3>
<ul>
<li>Usar instancias optimizadas pour memoria</li>
<li>ElastiCache pour sesiones</li>
<li>CloudFront pour assets estáticos</li>
<li>Auto Scaling basado en CPU. Pour proyectos enterprise, considera también
<a href="/fr/odoo-hosting/hosting-odoo-enterprise-empresarial-2025/" rel="internal">hosting enterprise dedicado</a></li>
</ul>
</div>
<div class="practice-card">
<h3>Seguridad</h3>
<ul>
<li>VPC con subredes privadas</li>
<li>Security Groups restrictivos</li>
<li>Encriptación con KMS</li>
<li>IAM roles granulares</li>
</ul>
</div>
<div class="practice-card">
<h3>Backups</h3>
<ul>
<li>Snapshots automáticos RDS</li>
<li>Lifecycle policies en S3</li>
<li>Cross-region replication</li>
<li>Disaster recovery plan</li>
</ul>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="cta-section">
<h2 class="cta-title">¿Listo pour migrar Odoo a AWS?</h2>
<p class="cta-subtitle">
Nuestro equipo de expertos certificados AWS puede ayudarte con la implementación.
Conoce más sobre <a href="https://aws.amazon.com/odoo/" target="_blank" rel="nofollow noopener">AWS pour aplicaciones empresariales</a>.
</p>
<div class="cta-actions">
<a href="#contacto" class="btn btn-primary btn-large">
Solicitar Consultoría
</a>
<a href="/recursos/guia-aws-odoo.pdf" class="btn btn-outline btn-large">
Descargar Guía PDF
</a>
</div>
</section>
</div>
<!-- ANIMATED HOSTING BANNER - A/B Testing Variation 1 -->
<script src="/components/hosting-banner-variations.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<script>
// Insert animated banner variation 1
if (window.location.pathname.includes('/odoo-hosting/')) {
document.write(createAnimatedHostingBannerVariation(1));
// Initialize D3 animations after banner is inserted
document.addEventListener('DOMContentLoaded', function() {
const bannerId = document.querySelector('.animated-hosting-banner-wrapper')?.id;
if (bannerId && typeof initializeBannerAnimations === 'function') {
// D3 animations would initialize here if defined
}
});
}
</script>
<script src="/components/eeat.min.js"></script>
<script>
document.write(createEEAT({
author: {
name: "Equipo Odoo Expertos",
title: "Expertos en Infraestructura Cloud",
experience: "10+ años implementando Odoo en AWS"
},
publishDate: "15 de enero de 2025",
modifiedDate: "27 de enero de 2025"
}));
</script>
<script src="/components/footer.min.js"></script>
<script>document.write(/*W6-static*/null);</script>
<script src="/js/cookie-banner.min.js"></script>
<!-- D3.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<script>
// Initialize banner animations after D3 is loaded
document.addEventListener('DOMContentLoaded', function() {
setTimeout(() => {
const bannerId = document.querySelector('.animated-hosting-banner-wrapper')?.id;
if (bannerId && typeof initializeBannerAnimations === 'function') {
initializeBannerAnimations(bannerId);
}
}, 100);
});
</script>
<script>
// AWS Ecosystem Force Network
function createAWSEcosystem() {
const container = d3.select("#aws-ecosystem");
const width = container.node().getBoundingClientRect().width;
const height = 400;
container.selectAll("*").remove();
const svg = container.append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);
// AWS Services data
const nodes = [
{id: "Odoo", group: 1, size: 40},
{id: "EC2", group: 2, size: 35},
{id: "RDS", group: 2, size: 35},
{id: "ELB", group: 2, size: 30},
{id: "S3", group: 3, size: 30},
{id: "CloudFront", group: 3, size: 25},
{id: "Route53", group: 3, size: 25},
{id: "VPC", group: 4, size: 25},
{id: "IAM", group: 4, size: 20},
{id: "CloudWatch", group: 4, size: 20},
{id: "Auto Scaling", group: 2, size: 25},
{id: "ElasticCache", group: 3, size: 20}
];
const links = [
{source: "Odoo", target: "EC2", strength: 3},
{source: "Odoo", target: "RDS", strength: 3},
{source: "EC2", target: "ELB", strength: 2},
{source: "EC2", target: "Auto Scaling", strength: 2},
{source: "Odoo", target: "S3", strength: 2},
{source: "S3", target: "CloudFront", strength: 2},
{source: "ELB", target: "Route53", strength: 2},
{source: "EC2", target: "VPC", strength: 1},
{source: "RDS", target: "VPC", strength: 1},
{source: "EC2", target: "CloudWatch", strength: 1},
{source: "RDS", target: "CloudWatch", strength: 1},
{source: "Odoo", target: "ElasticCache", strength: 1},
{source: "VPC", target: "IAM", strength: 1}
];
// Color scale for dark theme
const color = d3.scaleOrdinal()
.domain([1, 2, 3, 4])
.range(["#FF9500", "#FF6B35", "#F7435F", "#7B68EE"]);
// Force simulation
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(80))
.force("charge", d3.forceManyBody().strength(-300))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(d => d.size + 5));
// Create links
const link = svg.append("g")
.selectAll("line")
.data(links)
.join("line")
.attr("stroke", "#666")
.attr("stroke-opacity", 0.6)
.attr("stroke-width", d => Math.sqrt(d.strength) * 2);
// Create nodes
const node = svg.append("g")
.selectAll("g")
.data(nodes)
.join("g")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("circle")
.attr("r", d => d.size)
.attr("fill", d => color(d.group))
.attr("stroke", "#e0e0e0")
.attr("stroke-width", 2);
node.append("text")
.text(d => d.id)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-size", d => Math.min(d.size / 3, 12))
.attr("font-weight", "bold");
// Add hover effects
node.on("mouseover", function(event, d) {
d3.select(this).select("circle")
.transition()
.duration(200)
.attr("r", d.size * 1.2)
.attr("filter", "drop-shadow(0 0 10px rgba(255, 107, 53, 0.8))");
link.attr("stroke-opacity", l =>
l.source.id === d.id || l.target.id === d.id ? 1 : 0.1
);
})
.on("mouseout", function(event, d) {
d3.select(this).select("circle")
.transition()
.duration(200)
.attr("r", d.size)
.attr("filter", "none");
link.attr("stroke-opacity", 0.6);
});
// Update positions
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node.attr("transform", d => `translate(${d.x},${d.y})`);
});
// Drag functions
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
}
// Migration Timeline
function createMigrationTimeline() {
const container = d3.select("#migration-timeline");
const width = container.node().getBoundingClientRect().width;
const height = 300;
container.selectAll("*").remove();
const svg = container.append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);
const margin = {top: 40, right: 30, bottom: 50, left: 60};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// Timeline data
const data = [
{phase: "Análisis", start: 0, duration: 5, color: "#FF9500"},
{phase: "Prepourción", start: 3, duration: 7, color: "#FF6B35"},
{phase: "Migración", start: 8, duration: 4, color: "#F7435F"},
{phase: "Testing", start: 10, duration: 4, color: "#7B68EE"},
{phase: "Go Live", start: 12, duration: 2, color: "#4ECDC4"},
{phase: "Optimización", start: 14, duration: 6, color: "#95E1D3"}
];
// Scales
const xScale = d3.scaleLinear()
.domain([0, 20])
.range([0, innerWidth]);
const yScale = d3.scaleBand()
.domain(data.map(d => d.phase))
.range([0, innerHeight])
.padding(0.2);
// Create bars
g.selectAll(".bar")
.data(data)
.join("rect")
.attr("class", "bar")
.attr("x", d => xScale(d.start))
.attr("y", d => yScale(d.phase))
.attr("width", d => xScale(d.duration))
.attr("height", yScale.bandwidth())
.attr("fill", d => d.color)
.attr("rx", 4)
.style("opacity", 0)
.transition()
.duration(800)
.delay((d, i) => i * 100)
.style("opacity", 0.8);
// Add phase labels
g.selectAll(".label")
.data(data)
.join("text")
.attr("class", "label")
.attr("x", d => xScale(d.start) + xScale(d.duration) / 2)
.attr("y", d => yScale(d.phase) + yScale.bandwidth() / 2)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-size", "12px")
.attr("font-weight", "bold")
.text(d => d.phase);
// X axis
g.append("g")
.attr("transform", `translate(0,${innerHeight})`)
.call(d3.axisBottom(xScale).tickFormat(d => `Día ${d}`))
.style("color", "#999");
// Title
g.append("text")
.attr("x", innerWidth / 2)
.attr("y", -10)
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "#e0e0e0")
.text("Cronograma de Migración (20 días)");
}
// Hosting Comparison Matrix
function createHostingComparison() {
const container = d3.select("#hosting-comparison");
const width = container.node().getBoundingClientRect().width;
const height = 400;
container.selectAll("*").remove();
const svg = container.append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);
const margin = {top: 50, right: 120, bottom: 60, left: 60};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// Comparison data
const criteria = ["Costo", "Escalabilidad", "Performance", "Seguridad", "Soporte"];
const providers = [
{name: "AWS", values: [7, 10, 9, 10, 9], color: "#FF9500"},
{name: "On-Premise", values: [4, 3, 7, 6, 5], color: "#7B68EE"},
{name: "VPS Básico", values: [9, 4, 5, 5, 4], color: "#4ECDC4"}
];
// Scales
const xScale = d3.scaleBand()
.domain(criteria)
.range([0, innerWidth])
.padding(0.1);
const yScale = d3.scaleLinear()
.domain([0, 10])
.range([innerHeight, 0]);
// Create axes
g.append("g")
.attr("transform", `translate(0,${innerHeight})`)
.call(d3.axisBottom(xScale))
.style("color", "#999");
g.append("g")
.call(d3.axisLeft(yScale))
.style("color", "#999");
// Create bars for each provider
const barWidth = xScale.bandwidth() / providers.length;
providers.forEach((provider, i) => {
g.selectAll(`.bar-${i}`)
.data(provider.values)
.join("rect")
.attr("class", `bar-${i}`)
.attr("x", (d, j) => xScale(criteria[j]) + i * barWidth)
.attr("y", innerHeight)
.attr("width", barWidth - 2)
.attr("height", 0)
.attr("fill", provider.color)
.transition()
.duration(800)
.delay((d, j) => j * 100)
.attr("y", d => yScale(d))
.attr("height", d => innerHeight - yScale(d));
// Add value labels
g.selectAll(`.label-${i}`)
.data(provider.values)
.join("text")
.attr("class", `label-${i}`)
.attr("x", (d, j) => xScale(criteria[j]) + i * barWidth + barWidth / 2)
.attr("y", d => yScale(d) - 5)
.attr("text-anchor", "middle")
.attr("font-size", "11px")
.attr("fill", "#e0e0e0")
.style("opacity", 0)
.transition()
.duration(800)
.delay((d, j) => j * 100 + 400)
.style("opacity", 1)
.text(d => d);
});
// Legend
const legend = svg.append("g")
.attr("transform", `translate(${width - margin.right + 10}, ${margin.top})`);
providers.forEach((provider, i) => {
const legendItem = legend.append("g")
.attr("transform", `translate(0, ${i * 25})`);
legendItem.append("rect")
.attr("width", 18)
.attr("height", 18)
.attr("fill", provider.color);
legendItem.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.attr("font-size", "12px")
.attr("fill", "#e0e0e0")
.text(provider.name);
});
// Y axis label
g.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (innerHeight / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.style("font-size", "12px")
.style("fill", "#999")
.text("Puntuación (1-10)");
}
// Initialize visualizations when scrolled into view
const observerOptions = {
threshold: 0.1,
rootMargin: "0px 0px -100px 0px"
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.id;
switch(id) {
case 'aws-ecosystem':
createAWSEcosystem();
observer.unobserve(entry.target);
break;
case 'migration-timeline':
createMigrationTimeline();
observer.unobserve(entry.target);
break;
case 'hosting-comparison':
createHostingComparison();
observer.unobserve(entry.target);
break;
}
}
});
}, observerOptions);
// Observe visualization containers
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.chart-container').forEach(container => {
observer.observe(container);
});
});
// Handle window resize
let resizeTimer;
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
const ecosystem = document.querySelector('#aws-ecosystem');
if (ecosystem && ecosystem.getBoundingClientRect().top < window.innerHeight) {
createAWSEcosystem();
}
const timeline = document.querySelector('#migration-timeline');
if (timeline && timeline.getBoundingClientRect().top < window.innerHeight) {
createMigrationTimeline();
}
const comparison = document.querySelector('#hosting-comparison');
if (comparison && comparison.getBoundingClientRect().top < window.innerHeight) {
createHostingComparison();
}
}, 250);
});
</script>
</body>
</html>