diff --git a/app/static/index.html b/app/static/index.html index e1c0c54..c6e0fff 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -2786,86 +2786,88 @@ const utilizationPercentage = Math.min(100, Math.max(0, storageUtilization)); const unusedPercentage = 100 - utilizationPercentage; - // Create donut chart using Victory.js const container = document.getElementById('storage-donut-chart'); - // Clear container - container.innerHTML = ''; - - // Check if Victory is available - if (typeof Victory === 'undefined' || typeof React === 'undefined') { - throw new Error('Victory.js or React not available'); - } - - // Create donut chart data - const chartData = [ - { x: 'Used', y: utilizationPercentage }, - { x: 'Unused', y: unusedPercentage } - ]; - // Determine color based on utilization - const usedColor = utilizationPercentage >= 90 ? '#dc2626' : + const usedColor = utilizationPercentage >= 90 ? '#ef4444' : utilizationPercentage >= 75 ? '#f59e0b' : utilizationPercentage >= 50 ? '#3b82f6' : '#22c55e'; - // Create VictoryPie component - const donutChart = React.createElement(Victory.VictoryPie, { - data: chartData, - width: 300, - height: 300, - innerRadius: 80, - colorScale: [usedColor, '#374151'], - style: { - data: { - stroke: '#1f2937', - strokeWidth: 3 - } - }, - labels: () => null, - animate: { - duration: 1000, - onLoad: { duration: 500 } - } - }); + // Create SVG donut chart + const width = 250; + const height = 250; + const radius = Math.min(width, height) / 2 - 10; + const innerRadius = radius * 0.6; + const cx = width / 2; + const cy = height / 2; - // Create center text - const centerText = React.createElement('text', { - x: 150, - y: 140, - textAnchor: 'middle', - dominantBaseline: 'middle', - style: { - fontSize: '28px', - fontWeight: 'bold', - fill: '#f9fafb' - } - }, `${utilizationPercentage.toFixed(1)}%`); + // Calculate angles for the donut + const usedAngle = (utilizationPercentage / 100) * 360; + const unusedAngle = 360 - usedAngle; - // Create subtitle - const subtitle = React.createElement('text', { - x: 150, - y: 170, - textAnchor: 'middle', - dominantBaseline: 'middle', - style: { - fontSize: '14px', - fill: '#9ca3af' - } - }, `${formatBytes(totalStorageUsed)} used`); + // Convert angle to radians and create arc paths + const getPath = (angle) => { + const startAngle = -90; // Start from top + const endAngle = startAngle + angle; + const startAngleRad = (startAngle * Math.PI) / 180; + const endAngleRad = (endAngle * Math.PI) / 180; + + const x1 = cx + radius * Math.cos(startAngleRad); + const y1 = cy + radius * Math.sin(startAngleRad); + const x2 = cx + radius * Math.cos(endAngleRad); + const y2 = cy + radius * Math.sin(endAngleRad); + + const x3 = cx + innerRadius * Math.cos(endAngleRad); + const y3 = cy + innerRadius * Math.sin(endAngleRad); + const x4 = cx + innerRadius * Math.cos(startAngleRad); + const y4 = cy + innerRadius * Math.sin(startAngleRad); + + const largeArcFlag = angle > 180 ? 1 : 0; + + return `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2} L ${x3} ${y3} A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${x4} ${y4} Z`; + }; - // Create SVG container - const svgContainer = React.createElement('svg', { - width: 300, - height: 300, - viewBox: '0 0 300 300' - }, donutChart, centerText, subtitle); + const usedPath = getPath(usedAngle); + const unusedPath = getPath(unusedAngle); - // Render the chart - ReactDOM.render(svgContainer, container); + container.innerHTML = ` + + + + + + + + + + + + + + ${utilizationPercentage.toFixed(1)}% + + + + + ${formatBytes(totalStorageUsed)} + + + `; } catch (error) { console.error('Error updating storage donut chart:', error); - // Fallback to simple text display const container = document.getElementById('storage-donut-chart'); const storageUtilization = data.storage_utilization_percent || 0; const totalStorageUsed = data.total_storage_used || 0; @@ -2881,9 +2883,6 @@
${formatBytes(totalStorageUsed)} used
-
- Victory.js not available -
`; }