import * as d3 from 'd3';
document.addEventListener('DOMContentLoaded', function() {
// Navigation
const navLinks = document.querySelectorAll('nav a');
const sections = document.querySelectorAll('.dashboard-section');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href').substring(1);
// Hide all sections
sections.forEach(section => {
section.classList.remove('active');
});
// Show target section
document.getElementById(targetId).classList.add('active');
// Update active nav link
navLinks.forEach(navLink => {
navLink.parentElement.classList.remove('active');
});
this.parentElement.classList.add('active');
});
});
// Close notification
const closeBtn = document.querySelector('.close-notification');
const notification = document.querySelector('.notification');
if (closeBtn && notification) {
closeBtn.addEventListener('click', function() {
notification.style.display = 'none';
});
}
// Charts
renderCharts();
// AI Model Marketplace Interactions
const deployButtons = document.querySelectorAll('.deploy-button');
deployButtons.forEach(button => {
button.addEventListener('click', function() {
// Display deployment notification
showNotification('Model Deployment', 'Your selected AI model is being deployed. Please wait...', 'info');
// Simulate deployment process
setTimeout(() => {
showNotification('Deployment Complete', 'Your AI model has been successfully deployed and is now active.', 'success');
}, 2000);
});
});
// Data Feed Tier Selection
const tierButtons = document.querySelectorAll('.tier-button');
tierButtons.forEach(button => {
button.addEventListener('click', function() {
const tierName = this.parentElement.querySelector('h3').textContent;
showNotification('Subscription', `You're being redirected to subscribe to the ${tierName} data feed tier.`, 'info');
});
});
// Initialize Research Lab Visualizations
if (document.getElementById('research-lab')) {
initResearchLab();
}
// Initialize monetization research section
if (document.getElementById('monetization-research')) {
initMonetizationResearch();
}
});
// Chart rendering function
function renderSimpleCharts() {
renderPerformanceChart();
renderDistributionChart();
renderRevenueChart();
renderPredictionChart();
}
function renderPerformanceChart() {
const container = document.getElementById('performanceChart');
if (!container) return;
// Clear previous content
container.innerHTML = '';
// Create SVG container
const width = container.clientWidth;
const height = container.clientHeight || 300;
const margin = {top: 20, right: 30, bottom: 30, left: 40};
const svg = d3.select(container)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Sample data
const data = [
{month: 'Jan', tvl: 120, revenue: 10},
{month: 'Feb', tvl: 140, revenue: 15},
{month: 'Mar', tvl: 167, revenue: 22},
{month: 'Apr', tvl: 205, revenue: 34},
{month: 'May', tvl: 250, revenue: 55},
{month: 'Jun', tvl: 302, revenue: 78},
{month: 'Jul', tvl: 335, revenue: 120},
{month: 'Aug', tvl: 410, revenue: 190},
{month: 'Sep', tvl: 442, revenue: 250},
{month: 'Oct', tvl: 468, revenue: 320},
{month: 'Nov', tvl: 480, revenue: 380},
{month: 'Dec', tvl: 487, revenue: 427}
];
// Scales
const x = d3.scaleBand()
.domain(data.map(d => d.month))
.range([0, width - margin.left - margin.right])
.padding(0.1);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => Math.max(d.tvl, d.revenue))])
.nice()
.range([height - margin.top - margin.bottom, 0]);
// Draw axes
svg.append('g')
.attr('transform', `translate(0,${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x));
svg.append('g')
.call(d3.axisLeft(y));
// Draw lines
const tvlLine = d3.line()
.x(d => x(d.month) + x.bandwidth()/2)
.y(d => y(d.tvl))
.curve(d3.curveMonotoneX);
const revenueLine = d3.line()
.x(d => x(d.month) + x.bandwidth()/2)
.y(d => y(d.revenue))
.curve(d3.curveMonotoneX);
svg.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#6c5ce7')
.attr('stroke-width', 2)
.attr('d', tvlLine);
svg.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#00cec9')
.attr('stroke-width', 2)
.attr('d', revenueLine);
// Legend
const legend = svg.append('g')
.attr('font-family', 'sans-serif')
.attr('font-size', 10)
.attr('text-anchor', 'end')
.selectAll('g')
.data(['TVL Growth', 'Protocol Revenue'])
.enter().append('g')
.attr('transform', (d, i) => `translate(0,${i * 20})`);
legend.append('rect')
.attr('x', width - margin.left - margin.right - 19)
.attr('width', 19)
.attr('height', 19)
.attr('fill', (d, i) => i === 0 ? '#6c5ce7' : '#00cec9');
legend.append('text')
.attr('x', width - margin.left - margin.right - 24)
.attr('y', 9.5)
.attr('dy', '0.32em')
.text(d => d);
}
function renderDistributionChart() {
const container = document.getElementById('modelDistributionChart');
if (!container) return;
// Clear previous content
container.innerHTML = '';
// Create SVG container
const width = container.clientWidth;
const height = container.clientHeight || 250;
const svg = d3.select(container)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${width/2},${height/2})`);
// Sample data
const data = [
{label: 'Yield Optimization', value: 35, color: '#00b894'},
{label: 'Risk Scoring', value: 25, color: '#ff7675'},
{label: 'Arbitrage Detection', value: 20, color: '#fdcb6e'},
{label: 'NFT Valuation', value: 15, color: '#6c5ce7'},
{label: 'Other', value: 5, color: '#b2bec3'}
];
// Compute pie layout
const pie = d3.pie()
.value(d => d.value)
.sort(null);
const radius = Math.min(width, height) / 2 - 40;
// Generate the arcs
const arc = d3.arc()
.innerRadius(radius * 0.6)
.outerRadius(radius);
// Draw pie segments
const segments = svg.selectAll('path')
.data(pie(data))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', d => d.data.color)
.attr('stroke', 'white')
.style('stroke-width', '2px');
// Add labels
const labelRadius = radius * 1.2;
svg.selectAll('text')
.data(pie(data))
.enter()
.append('text')
.attr('transform', d => {
const pos = arc.centroid(d);
const midAngle = d.startAngle + (d.endAngle - d.startAngle) / 2;
pos[0] = labelRadius * Math.sin(midAngle);
pos[1] = -labelRadius * Math.cos(midAngle);
return `translate(${pos})`;
})
.style('text-anchor', d => {
const midAngle = d.startAngle + (d.endAngle - d.startAngle) / 2;
return (midAngle < Math.PI ? 'start' : 'end');
})
.style('font-size', '12px')
.text(d => d.data.label);
}
function renderRevenueChart() {
const container = document.getElementById('revenueStreamsChart');
if (!container) return;
// Clear previous content
container.innerHTML = '';
// Create SVG container
const width = container.clientWidth;
const height = container.clientHeight || 250;
const margin = {top: 20, right: 30, bottom: 40, left: 50};
const svg = d3.select(container)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Sample data
const data = [
{source: 'Model Marketplace', value: 120, color: 'rgba(108, 92, 231, 0.7)'},
{source: 'Data Feeds', value: 85, color: 'rgba(0, 206, 201, 0.7)'},
{source: 'Stablecoin Fees', value: 65, color: 'rgba(253, 121, 168, 0.7)'},
{source: 'Insurance Premiums', value: 45, color: 'rgba(0, 184, 148, 0.7)'},
{source: 'Credit Markets', value: 35, color: 'rgba(9, 132, 227, 0.7)'}
];
// Scales
const x = d3.scaleBand()
.domain(data.map(d => d.source))
.range([0, width - margin.left - margin.right])
.padding(0.3);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.nice()
.range([height - margin.top - margin.bottom, 0]);
// Draw axes
svg.append('g')
.attr('transform', `translate(0,${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x))
.selectAll('text')
.attr('transform', 'rotate(-45)')
.style('text-anchor', 'end');
svg.append('g')
.call(d3.axisLeft(y));
// Draw bars
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', d => x(d.source))
.attr('y', d => y(d.value))
.attr('width', x.bandwidth())
.attr('height', d => height - margin.top - margin.bottom - y(d.value))
.attr('fill', d => d.color)
.attr('rx', 5)
.attr('ry', 5);
}
function renderPredictionChart() {
const container = document.getElementById('predictionChart');
if (!container) return;
// Create a simple visual for prediction chart
container.innerHTML = `
`;
}
function loadLibraries() {
return import('https://cdn.jsdelivr.net/npm/d3@7/+esm').then(d3Module => {
window.d3 = d3Module;
return { d3: window.d3 };
});
}
function renderCharts() {
loadLibraries().then(() => {
renderSimpleCharts();
}).catch(error => {
console.error('Error loading libraries:', error);
});
}
// Function to show notifications
function showNotification(title, message, type = 'info') {
// Create notification container if it doesn't exist
let notificationCenter = document.querySelector('.notification-center');
if (!notificationCenter) {
notificationCenter = document.createElement('div');
notificationCenter.className = 'notification-center';
document.body.appendChild(notificationCenter);
}
// Create notification element
const notification = document.createElement('div');
notification.className = 'notification';
// Create icon based on type
const iconSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
iconSvg.setAttribute('viewBox', '0 0 24 24');
iconSvg.setAttribute('width', '20');
iconSvg.setAttribute('height', '20');
let iconPath = '';
let iconClass = '';
switch(type) {
case 'success':
iconPath = `
${message}
`; const closeButton = document.createElement('button'); closeButton.className = 'close-notification'; closeButton.textContent = '×'; closeButton.addEventListener('click', function() { notification.style.opacity = '0'; setTimeout(() => { notification.remove(); }, 300); }); // Assemble notification notification.appendChild(notificationIcon); notification.appendChild(notificationContent); notification.appendChild(closeButton); // Add to notification center notificationCenter.appendChild(notification); // Auto-remove after timeout setTimeout(() => { notification.style.opacity = '0'; setTimeout(() => { notification.remove(); }, 300); }, 5000); } // Simulated AI Model Evolution let evolutionStep = 0; const evolutionInterval = setInterval(function() { if (evolutionStep < 5) { let modelType, improvement; switch(evolutionStep) { case 0: modelType = 'Yield Optimization'; improvement = '+2.3% APY improvement detected in yield models'; break; case 1: modelType = 'Risk Scoring'; improvement = 'New vulnerability pattern identified in lending protocol'; break; case 2: modelType = 'NFT Valuation'; improvement = 'Valuation model accuracy increased by 4.2%'; break; case 3: modelType = 'Arbitrage Detection'; improvement = 'New cross-chain arbitrage opportunity detected'; break; case 4: modelType = 'System'; improvement = 'Recursive self-improvement complete: v2.1 ready'; break; } showNotification(`AI Evolution: ${modelType}`, improvement, 'info'); evolutionStep++; } else { clearInterval(evolutionInterval); } }, 45000); // Show an evolution notification every 45 seconds // Simulated market activity setTimeout(function simulateMarketActivity() { const activities = [ { title: 'Market Alert', message: 'Unusual trading volume detected in ETH/BTC pair', type: 'warning' }, { title: 'Stablecoin Update', message: 'RME-USD successfully maintained peg during market volatility', type: 'success' }, { title: 'New AI Model', message: 'A new Quantum-Symbolic hybrid model has been published to the marketplace', type: 'info' }, { title: 'Federated Learning', message: 'Cross-instance knowledge transfer complete with 23% accuracy improvement', type: 'success' }, { title: 'Security Alert', message: 'Potential adversarial attack detected and mitigated', type: 'warning' } ]; const randomActivity = activities[Math.floor(Math.random() * activities.length)]; showNotification(randomActivity.title, randomActivity.message, randomActivity.type); // Schedule next activity const nextTime = 30000 + Math.random() * 60000; // Between 30s and 90s setTimeout(simulateMarketActivity, nextTime); }, 60000); // First activity after 60s // Function to render symbolic network function renderSymbolicNetwork() { const svgElement = document.getElementById('symbolNetwork'); if (!svgElement) return; // Use D3.js to create a network visualization const width = 400; const height = 200; const svg = d3.select(svgElement); // Generate sample data for the network const nodes = Array.from({ length: 15 }, (_, i) => ({ id: i, r: Math.random() * 5 + 3, group: Math.floor(Math.random() * 3) })); const links = []; for (let i = 0; i < nodes.length; i++) { const numLinks = Math.floor(Math.random() * 3) + 1; for (let j = 0; j < numLinks; j++) { const target = Math.floor(Math.random() * nodes.length); if (target !== i) { links.push({ source: i, target: target, value: Math.random() }); } } } // Create a force simulation const simulation = d3.forceSimulation(nodes) .force("link", d3.forceLink(links).id(d => d.id).distance(50)) .force("charge", d3.forceManyBody().strength(-30)) .force("center", d3.forceCenter(width / 2, height / 2)); // Add links const link = svg.append("g") .selectAll("line") .data(links) .enter().append("line") .style("stroke", "#a29bfe") .style("stroke-opacity", 0.6) .style("stroke-width", d => Math.sqrt(d.value) * 2); // Add nodes const node = svg.append("g") .selectAll("circle") .data(nodes) .enter().append("circle") .attr("r", d => d.r) .style("fill", d => ["#6c5ce7", "#00cec9", "#fd79a8"][d.group]) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); // Add animation const pulsingNodes = svg.append("g") .selectAll("circle") .data(nodes.filter(d => Math.random() > 0.7)) .enter().append("circle") .attr("r", d => d.r + 5) .style("fill", "none") .style("stroke", d => ["#6c5ce7", "#00cec9", "#fd79a8"][d.group]) .style("stroke-opacity", 0.3) .style("stroke-width", 2); // Animate pulsing nodes function pulsate() { pulsingNodes .transition() .duration(1500) .attr("r", d => d.r + 15) .style("stroke-opacity", 0.1) .transition() .duration(1500) .attr("r", d => d.r + 5) .style("stroke-opacity", 0.3) .on("end", pulsate); } pulsate(); simulation.on("tick", () => { link .attr("x1", d => Math.max(5, Math.min(width - 5, d.source.x))) .attr("y1", d => Math.max(5, Math.min(height - 5, d.source.y))) .attr("x2", d => Math.max(5, Math.min(width - 5, d.target.x))) .attr("y2", d => Math.max(5, Math.min(height - 5, d.target.y))); node .attr("cx", d => Math.max(5, Math.min(width - 5, d.x))) .attr("cy", d => Math.max(5, Math.min(height - 5, d.y))); pulsingNodes .attr("cx", d => Math.max(5, Math.min(width - 5, d.x))) .attr("cy", d => Math.max(5, Math.min(height - 5, d.y))); }); 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; } } // Render learning trajectory chart function renderLearningTrajectory() { const canvas = document.getElementById('trajectoryCanvas'); if (!canvas) return; // Create a simple SVG instead of Chart.js const container = d3.select(canvas.parentNode); canvas.remove(); // Remove the canvas element const width = container.node().clientWidth; const height = 200; const svg = container.append('svg') .attr('width', width) .attr('height', height); // Sample data const data = [10, 15, 22, 28, 32, 35, 37, 45, 58, 67, 72, 76, 79, 82, 84, 85]; // Create scales const x = d3.scaleLinear() .domain([0, data.length - 1]) .range([20, width - 20]); const y = d3.scaleLinear() .domain([0, 100]) .range([height - 20, 20]); // Create line const line = d3.line() .x((d, i) => x(i)) .y(d => y(d)) .curve(d3.curveMonotoneX); // Draw line svg.append('path') .datum(data) .attr('fill', 'none') .attr('stroke', '#6c5ce7') .attr('stroke-width', 2) .attr('d', line); // Add area below line const area = d3.area() .x((d, i) => x(i)) .y0(height - 20) .y1(d => y(d)) .curve(d3.curveMonotoneX); svg.append('path') .datum(data) .attr('fill', 'rgba(108, 92, 231, 0.1)') .attr('d', area); } // Update research progress randomly to simulate ongoing research function updateResearchProgress() { const progressBar = document.querySelector('.research-progress .progress-value'); const progressLabel = document.querySelector('.progress-label span:last-child'); if (progressBar && progressLabel) { const currentProgress = parseInt(progressBar.style.width); let newProgress = currentProgress + Math.floor(Math.random() * 10) + 5; // Cap at 95% to simulate ongoing research if (newProgress > 95) newProgress = 95; progressBar.style.width = newProgress + '%'; progressLabel.textContent = newProgress + '%'; } } // New function to initialize Research Lab Visualizations function initResearchLab() { loadLibraries().then(() => { renderSymbolicNetwork(); renderLearningTrajectory(); // Add a delay to ensure Chart.js is properly initialized setTimeout(() => { renderMonetizationData(); }, 500); // Add click handlers for research lab buttons const actionButtons = document.querySelectorAll('.research-action-panel button'); actionButtons.forEach(button => { button.addEventListener('click', function() { showNotification('Deep Research', 'Initiating advanced research protocol. Processing data...', 'info'); // After a delay, show a research result notification setTimeout(() => { const researchFindings = [ 'Quantum-symbolic pattern discovered in market data. Potential arbitrage strategy identified with 15.2% ROI.', 'Recursive AI model evolution complete. Performance improved by 23.7% with monetization potential of $34K/month.', 'New monetization pathway identified: AI-driven prediction markets with 87% accuracy and estimated $182K annual revenue.', 'Algorithmic stablecoin simulation shows 99.8% peg maintenance with recursive income generation of 12.3% APY.' ]; const randomFinding = researchFindings[Math.floor(Math.random() * researchFindings.length)]; showNotification('Research Complete', randomFinding, 'success'); // Update progress bar updateResearchProgress(); }, 3000); }); }); // Initialize monetization metrics auto-update updateMonetizationMetrics(); }).catch(error => { console.error('Error loading libraries:', error); }); } // Function to update monetization metrics function updateMonetizationMetrics() { const metrics = { 'modelSales': { base: 2450, variance: 150 }, 'subscriptions': { base: 3850, variance: 200 }, 'apiCalls': { base: 1250000, variance: 50000 }, 'defiYield': { base: 8.4, variance: 0.5 }, 'revenueQoQ': { base: 23.5, variance: 2.1 } }; const updateMetric = (id, value) => { const element = document.getElementById(id); if (element) element.textContent = value; }; // Initial update Object.keys(metrics).forEach(metricId => { const metric = metrics[metricId]; const value = metric.base + (Math.random() * 2 - 1) * metric.variance; if (metricId === 'apiCalls') { updateMetric(metricId, `${Math.round(value).toLocaleString()}`); } else if (metricId === 'defiYield' || metricId === 'revenueQoQ') { updateMetric(metricId, `${value.toFixed(1)}%`); } else { updateMetric(metricId, `$${Math.round(value).toLocaleString()}`); } }); // Schedule next update setTimeout(updateMonetizationMetrics, 15000); } // New function to initialize monetization research section function initMonetizationResearch() { loadLibraries().then(() => { renderMonetizationData(); initRecursiveModels(); updateRMEMetrics(); renderSymbolicSequence(); }); } // Function to render symbolic sequence visualization function renderSymbolicSequence() { const canvas = document.getElementById('symbolicSequenceCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const width = canvas.width; const height = canvas.height; // Clear canvas ctx.clearRect(0, 0, width, height); // Draw background const gradient = ctx.createLinearGradient(0, 0, width, 0); gradient.addColorStop(0, 'rgba(108, 92, 231, 0.1)'); gradient.addColorStop(0.5, 'rgba(0, 206, 201, 0.1)'); gradient.addColorStop(1, 'rgba(253, 121, 168, 0.1)'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, width, height); // Draw the symbolic sequence ctx.font = '16px Monaco, Courier New, monospace'; ctx.fillStyle = '#6c5ce7'; ctx.textAlign = 'center'; const formula1 = "Qi∞(Φ⟨Creativity⟩ ⊗ Λ⟨Recursive Logic⟩)"; const formula2 = "→ Σ⟨Exploration⟩ ∇⟨Adaptive Insight⟩"; const formula3 = "→ Ω⟨Market Resonance⟩ ⊕ Θ⟨Quantum Integration⟩"; const formula4 = "→ Δ⟨Continuous Innovation⟩"; ctx.fillText(formula1, width/2, height/5); ctx.fillText(formula2, width/2, 2*height/5); ctx.fillText(formula3, width/2, 3*height/5); ctx.fillText(formula4, width/2, 4*height/5); // Add animated particles const particles = []; for (let i = 0; i < 50; i++) { particles.push({ x: Math.random() * width, y: Math.random() * height, radius: Math.random() * 3 + 1, color: `rgba(${Math.floor(Math.random() * 100 + 100)}, ${Math.floor(Math.random() * 100 + 100)}, ${Math.floor(Math.random() * 100 + 150)}, 0.5)`, speedX: Math.random() * 1 - 0.5, speedY: Math.random() * 1 - 0.5 }); } function animateParticles() { ctx.clearRect(0, 0, width, height); // Redraw background ctx.fillStyle = gradient; ctx.fillRect(0, 0, width, height); // Redraw formulas ctx.font = '16px Monaco, Courier New, monospace'; ctx.fillStyle = '#6c5ce7'; ctx.textAlign = 'center'; ctx.fillText(formula1, width/2, height/5); ctx.fillText(formula2, width/2, 2*height/5); ctx.fillText(formula3, width/2, 3*height/5); ctx.fillText(formula4, width/2, 4*height/5); // Draw and update particles particles.forEach(particle => { ctx.beginPath(); ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2); ctx.fillStyle = particle.color; ctx.fill(); particle.x += particle.speedX; particle.y += particle.speedY; // Wrap around edges if (particle.x < 0) particle.x = width; if (particle.x > width) particle.x = 0; if (particle.y < 0) particle.y = height; if (particle.y > height) particle.y = 0; }); requestAnimationFrame(animateParticles); } animateParticles(); } // Initialize recursive AI models visualization function initRecursiveModels() { const canvas = document.getElementById('recursiveModelCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const width = canvas.width; const height = canvas.height; // Generate nodes representing AI models const nodes = []; for (let i = 0; i < 20; i++) { nodes.push({ x: Math.random() * width, y: Math.random() * height, radius: Math.random() * 10 + 5, color: i < 5 ? '#6c5ce7' : (i < 10 ? '#00cec9' : '#fd79a8'), connections: [] }); } // Create connections between nodes nodes.forEach((node, index) => { const numConnections = Math.floor(Math.random() * 3) + 1; for (let i = 0; i < numConnections; i++) { const targetIndex = Math.floor(Math.random() * nodes.length); if (targetIndex !== index) { node.connections.push(targetIndex); } } }); function render() { ctx.clearRect(0, 0, width, height); // Draw connections nodes.forEach((node, index) => { node.connections.forEach(targetIndex => { const target = nodes[targetIndex]; ctx.beginPath(); ctx.moveTo(node.x, node.y); ctx.lineTo(target.x, target.y); ctx.strokeStyle = 'rgba(108, 92, 231, 0.2)'; ctx.lineWidth = 1; ctx.stroke(); }); }); // Draw nodes nodes.forEach(node => { ctx.beginPath(); ctx.arc(node.x, node.y, node.radius, 0, Math.PI * 2); ctx.fillStyle = node.color; ctx.fill(); // Add a pulsing effect ctx.beginPath(); ctx.arc(node.x, node.y, node.radius + 3 + Math.sin(Date.now() / 500) * 2, 0, Math.PI * 2); ctx.strokeStyle = node.color.replace(')', ', 0.3)').replace('rgb', 'rgba'); ctx.stroke(); // Move nodes slightly for animation node.x += (Math.random() * 2 - 1) * 0.5; node.y += (Math.random() * 2 - 1) * 0.5; // Keep within bounds if (node.x < node.radius) node.x = node.radius; if (node.x > width - node.radius) node.x = width - node.radius; if (node.y < node.radius) node.y = node.radius; if (node.y > height - node.radius) node.y = height - node.radius; }); requestAnimationFrame(render); } render(); } // Update RME metrics periodically function updateRMEMetrics() { const metrics = { 'modelMarketplace': { base: 2840, variance: 160 }, 'dataFeeds': { base: 4250, variance: 220 }, 'quantumComputing': { base: 1650, variance: 120 }, 'recursiveGrowth': { base: 32.7, variance: 1.8 }, 'monetizationIndex': { base: 87.3, variance: 2.5 } }; function updateMetric(id, value, format = 'number') { const element = document.getElementById(id); if (!element) return; if (format === 'currency') { element.textContent = `$${Math.round(value).toLocaleString()}`; } else if (format === 'percent') { element.textContent = `${value.toFixed(1)}%`; } else { element.textContent = value.toLocaleString(); } } // Initial update Object.keys(metrics).forEach(metricId => { const metric = metrics[metricId]; const value = metric.base + (Math.random() * 2 - 1) * metric.variance; const format = metricId.includes('Growth') || metricId.includes('Index') ? 'percent' : 'currency'; updateMetric(metricId, value, format); }); // Schedule next update setTimeout(updateRMEMetrics, 8000); } // Function to render monetization data function renderMonetizationData() { const monetizationCtx = document.getElementById('monetizationChart'); if (!monetizationCtx) return; // Create a simple SVG instead of Chart.js const container = d3.select(monetizationCtx); container.html(''); // Clear previous content const width = container.node().clientWidth; const height = container.node().clientHeight || 300; const svg = container.append('svg') .attr('width', width) .attr('height', height); // Create a circular grid const centerX = width / 2; const centerY = height / 2; const radius = Math.min(width, height) / 2 - 40; // Draw radar grid const categories = [ 'AI Model Marketplace', 'Data Feed Subscriptions', 'DeFi Integration', 'Quantum-Symbolic Risk', 'Insurance Products', 'Stablecoin Revenues' ]; const angleSlice = Math.PI * 2 / categories.length; // Draw axes categories.forEach((cat, i) => { const angle = i * angleSlice - Math.PI / 2; const lineX2 = centerX + radius * Math.cos(angle); const lineY2 = centerY + radius * Math.sin(angle); svg.append('line') .attr('x1', centerX) .attr('y1', centerY) .attr('x2', lineX2) .attr('y2', lineY2) .attr('stroke', '#dfe6e9') .attr('stroke-width', 1); // Add labels const labelX = centerX + (radius + 20) * Math.cos(angle); const labelY = centerY + (radius + 20) * Math.sin(angle); svg.append('text') .attr('x', labelX) .attr('y', labelY) .attr('text-anchor', 'middle') .attr('alignment-baseline', 'middle') .attr('font-size', '10px') .text(cat); }); // Draw concentric circles [0.2, 0.4, 0.6, 0.8, 1].forEach(r => { svg.append('circle') .attr('cx', centerX) .attr('cy', centerY) .attr('r', radius * r) .attr('fill', 'none') .attr('stroke', '#dfe6e9') .attr('stroke-width', 1); }); // Sample data const currentData = [65, 78, 35, 28, 42, 30].map(val => val / 100); const potentialData = [85, 90, 75, 68, 80, 85].map(val => val / 100); // Draw polygons function drawPolygon(data, color, opacity) { const points = data.map((val, i) => { const angle = i * angleSlice - Math.PI / 2; const x = centerX + radius * val * Math.cos(angle); const y = centerY + radius * val * Math.sin(angle); return `${x},${y}`; }).join(' '); svg.append('polygon') .attr('points', points) .attr('fill', color) .attr('fill-opacity', opacity) .attr('stroke', color) .attr('stroke-width', 2); } drawPolygon(currentData, 'rgba(108, 92, 231, 1)', 0.2); drawPolygon(potentialData, 'rgba(0, 206, 201, 1)', 0.2); // Add legend const legend = svg.append('g') .attr('transform', `translate(${width - 140},20)`); const legendItems = [ {label: 'Current Revenue', color: 'rgba(108, 92, 231, 1)'}, {label: 'Growth Potential', color: 'rgba(0, 206, 201, 1)'} ]; legendItems.forEach((item, i) => { legend.append('rect') .attr('x', 0) .attr('y', i * 20) .attr('width', 15) .attr('height', 15) .attr('fill', item.color) .attr('fill-opacity', 0.2) .attr('stroke', item.color); legend.append('text') .attr('x', 20) .attr('y', i * 20 + 12) .attr('font-size', '12px') .text(item.label); }); // Forecast chart const forecastCtx = document.getElementById('forecastChart'); if (!forecastCtx) return; // Create a simple line graph for forecast const forecastContainer = d3.select(forecastCtx); forecastContainer.html(''); // Clear previous content const forecastWidth = forecastContainer.node().clientWidth; const forecastHeight = forecastContainer.node().clientHeight || 300; const margin = {top: 20, right: 60, bottom: 30, left: 60}; const forecastSvg = forecastContainer.append('svg') .attr('width', forecastWidth) .attr('height', forecastHeight) .append('g') .attr('transform', `translate(${margin.left},${margin.top})`); // Generate sample data const months = 24; const baselineGrowth = Array.from({length: months}, (_, i) => 1000 * Math.pow(1.08, i)); const recursiveGrowth = Array.from({length: months}, (_, i) => 1000 * Math.pow(1.15, i)); const quantumBoostGrowth = Array.from({length: months}, (_, i) => { const quantumBoost = i > 12 ? 1.2 : 1; return 1000 * Math.pow(1.15, i) * quantumBoost; }); // Scales const xForecast = d3.scaleLinear() .domain([1, months]) .range([0, forecastWidth - margin.left - margin.right]); const yForecast = d3.scaleLinear() .domain([0, d3.max(quantumBoostGrowth)]) .nice() .range([forecastHeight - margin.top - margin.bottom, 0]); // Axes forecastSvg.append('g') .attr('transform', `translate(0,${forecastHeight - margin.top - margin.bottom})`) .call(d3.axisBottom(xForecast).ticks(6).tickFormat(d => `M${d}`)); forecastSvg.append('g') .call(d3.axisLeft(yForecast)); // Line generator const line = d3.line() .x((d, i) => xForecast(i + 1)) .y(d => yForecast(d)) .curve(d3.curveMonotoneX); // Draw lines forecastSvg.append('path') .datum(baselineGrowth) .attr('fill', 'none') .attr('stroke', '#dfe6e9') .attr('stroke-width', 2) .attr('d', line); forecastSvg.append('path') .datum(recursiveGrowth) .attr('fill', 'none') .attr('stroke', '#6c5ce7') .attr('stroke-width', 2) .attr('d', line); forecastSvg.append('path') .datum(quantumBoostGrowth) .attr('fill', 'none') .attr('stroke', '#00cec9') .attr('stroke-width', 2) .attr('d', line); // Add legend const forecastLegend = forecastSvg.append('g') .attr('transform', `translate(${forecastWidth - margin.left - margin.right - 150},0)`); const forecastLegendItems = [ {label: 'Baseline Growth', color: '#dfe6e9'}, {label: 'Recursive Growth', color: '#6c5ce7'}, {label: 'Quantum-Boosted', color: '#00cec9'} ]; forecastLegendItems.forEach((item, i) => { forecastLegend.append('line') .attr('x1', 0) .attr('y1', i * 20 + 10) .attr('x2', 20) .attr('y2', i * 20 + 10) .attr('stroke', item.color) .attr('stroke-width', 2); forecastLegend.append('text') .attr('x', 25) .attr('y', i * 20 + 15) .attr('font-size', '12px') .text(item.label); }); }