Fix graph of health
This commit is contained in:
		
							
								
								
									
										11
									
								
								pvc-vue/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								pvc-vue/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -10,7 +10,8 @@ | ||||
|       "dependencies": { | ||||
|         "@fortawesome/fontawesome-free": "^6.7.2", | ||||
|         "bootstrap": "^5.3.3", | ||||
|         "chart.js": "^4.4.8", | ||||
|         "chart.js": "^4.4.1", | ||||
|         "chartjs-plugin-annotation": "^3.0.1", | ||||
|         "pinia": "^3.0.1", | ||||
|         "vue": "^3.5.13", | ||||
|         "vue-chartjs": "^5.3.2" | ||||
| @@ -983,6 +984,14 @@ | ||||
|         "pnpm": ">=8" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/chartjs-plugin-annotation": { | ||||
|       "version": "3.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.1.0.tgz", | ||||
|       "integrity": "sha512-EkAed6/ycXD/7n0ShrlT1T2Hm3acnbFhgkIEJLa0X+M6S16x0zwj1Fv4suv/2bwayCT3jGPdAtI9uLcAMToaQQ==", | ||||
|       "peerDependencies": { | ||||
|         "chart.js": ">=4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/copy-anything": { | ||||
|       "version": "3.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", | ||||
|   | ||||
| @@ -11,10 +11,11 @@ | ||||
|   "dependencies": { | ||||
|     "@fortawesome/fontawesome-free": "^6.7.2", | ||||
|     "bootstrap": "^5.3.3", | ||||
|     "chart.js": "^4.4.8", | ||||
|     "chart.js": "^4.4.1", | ||||
|     "pinia": "^3.0.1", | ||||
|     "vue": "^3.5.13", | ||||
|     "vue-chartjs": "^5.3.2" | ||||
|     "vue-chartjs": "^5.3.2", | ||||
|     "chartjs-plugin-annotation": "^3.0.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@vitejs/plugin-vue": "^5.2.1", | ||||
|   | ||||
| @@ -25,7 +25,10 @@ | ||||
|       </div> | ||||
|       <div class="content-grid"> | ||||
|         <div class="overview-row"> | ||||
|           <ClusterOverview :clusterData="clusterData" /> | ||||
|           <ClusterOverview  | ||||
|             :clusterData="clusterData" | ||||
|             :metricsHistory="metricsHistory.health" | ||||
|           /> | ||||
|           <NodeStatus :nodeData="nodeData" /> | ||||
|         </div> | ||||
|         <MetricsCharts :metricsData="metricsHistory" class="metrics-section" /> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|         <div class="health-card"> | ||||
|           <div class="card-body"> | ||||
|             <h6 class="card-subtitle mb-2 text-muted">Cluster Health</h6> | ||||
|             <div class="health-content"> | ||||
|             <div class="health-content-wrapper"> | ||||
|               <div class="health-graph"> | ||||
|                 <div class="health-percentage"> | ||||
|                   <h4 :class="['health-title', getHealthClass(clusterData.cluster_health?.health)]"> | ||||
| @@ -116,6 +116,7 @@ import { | ||||
|   Legend, | ||||
|   Filler | ||||
| } from 'chart.js'; | ||||
| import annotationPlugin from 'chartjs-plugin-annotation'; | ||||
|  | ||||
| // Register Chart.js components | ||||
| ChartJS.register( | ||||
| @@ -126,7 +127,8 @@ ChartJS.register( | ||||
|   Title, | ||||
|   Tooltip, | ||||
|   Legend, | ||||
|   Filler | ||||
|   Filler, | ||||
|   annotationPlugin | ||||
| ); | ||||
|  | ||||
| const props = defineProps({ | ||||
| @@ -134,6 +136,11 @@ const props = defineProps({ | ||||
|     type: Object, | ||||
|     required: true, | ||||
|     default: () => ({}) | ||||
|   }, | ||||
|   metricsHistory: { | ||||
|     type: Object, | ||||
|     required: true, | ||||
|     default: () => ({ labels: [], data: [] }) | ||||
|   } | ||||
| }); | ||||
|  | ||||
| @@ -153,19 +160,10 @@ const healthChartData = computed(() => { | ||||
|   const health = props.clusterData.cluster_health?.health || 0; | ||||
|   const colors = getHealthColors(health); | ||||
|    | ||||
|   // Create sample data if health_history is not available | ||||
|   const now = Date.now(); | ||||
|   const defaultData = Array.from({length: 20}, (_, i) => ({ | ||||
|     time: now - (19 - i) * 1000, | ||||
|     value: health | ||||
|   })); | ||||
|  | ||||
|   const dataPoints = props.clusterData.health_history || defaultData; | ||||
|  | ||||
|   return { | ||||
|     labels: dataPoints.map(point => new Date(point.time).toLocaleTimeString()), | ||||
|     labels: props.metricsHistory.labels, | ||||
|     datasets: [{ | ||||
|       data: dataPoints.map(point => point.value), | ||||
|       data: props.metricsHistory.data, | ||||
|       fill: true, | ||||
|       backgroundColor: colors.bg, | ||||
|       borderColor: colors.border, | ||||
| @@ -180,25 +178,49 @@ const healthChartData = computed(() => { | ||||
| const healthChartOptions = { | ||||
|   responsive: true, | ||||
|   maintainAspectRatio: false, | ||||
|   clip: false, | ||||
|   plugins: { | ||||
|     legend: { | ||||
|       display: false | ||||
|     }, | ||||
|     tooltip: { | ||||
|       callbacks: { | ||||
|         label: (context) => `${context.parsed.y}%` | ||||
|       } | ||||
|     }, | ||||
|     annotation: { | ||||
|       annotations: { | ||||
|         warning: { | ||||
|           type: 'line', | ||||
|           yMin: 90, | ||||
|           yMax: 90, | ||||
|           borderColor: 'rgba(255, 193, 7, 0.2)', | ||||
|           borderWidth: 1, | ||||
|         }, | ||||
|         danger: { | ||||
|           type: 'line', | ||||
|           yMin: 50, | ||||
|           yMax: 50, | ||||
|           borderColor: 'rgba(220, 53, 69, 0.2)', | ||||
|           borderWidth: 1, | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   scales: { | ||||
|     x: { | ||||
|       display: false, | ||||
|       grid: { | ||||
|         display: false, | ||||
|       }, | ||||
|         display: false | ||||
|       } | ||||
|     }, | ||||
|     y: { | ||||
|       display: false, | ||||
|       grid: { | ||||
|         display: false, | ||||
|         display: false | ||||
|       }, | ||||
|       min: 0, | ||||
|       max: 100, | ||||
|       max: 100 | ||||
|     } | ||||
|   }, | ||||
|   animation: false, | ||||
| @@ -225,18 +247,21 @@ const healthChartOptions = { | ||||
|   height: 100%; | ||||
| } | ||||
|  | ||||
| .health-content { | ||||
| .health-content-wrapper { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 0.5rem; | ||||
|   min-height: 300px; | ||||
|   height: auto; | ||||
|   height: calc(100% - 2rem); /* Account for header */ | ||||
|   width: 100%; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .health-graph { | ||||
|   position: relative; | ||||
|   height: 200px; | ||||
|   flex-grow: 1; | ||||
|   min-height: 0; /* Allow shrinking */ | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .health-percentage { | ||||
| @@ -262,7 +287,11 @@ const healthChartOptions = { | ||||
|   padding: 0.5rem; | ||||
|   background: rgba(0, 0, 0, 0.02); | ||||
|   border-radius: 0.25rem; | ||||
|   flex-grow: 1; | ||||
|   position: relative; | ||||
|   bottom: 0; | ||||
|   min-height: 2.5rem; | ||||
|   max-height: 30%; /* Reduce maximum height */ | ||||
|   overflow-y: auto; | ||||
| } | ||||
|  | ||||
| .messages-grid { | ||||
| @@ -291,7 +320,11 @@ const healthChartOptions = { | ||||
| } | ||||
|  | ||||
| .health-message:hover { | ||||
|   background: rgba(220, 53, 69, 0.15); | ||||
|   background: rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .health-message.healthy:hover { | ||||
|   background: rgba(40, 167, 69, 0.15); | ||||
| } | ||||
|  | ||||
| .health-message:hover::after { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user