mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-11-01 00:15:05 +01:00 
			
		
		
		
	feat: Rework analysis view top to contain piechart
This commit is contained in:
		| @@ -6,7 +6,8 @@ | |||||||
|     import Filters from './filters/Filters.svelte' |     import Filters from './filters/Filters.svelte' | ||||||
|     import PlotSelection from './PlotSelection.svelte' |     import PlotSelection from './PlotSelection.svelte' | ||||||
|     import Histogramuplot from './plots/Histogramuplot.svelte' |     import Histogramuplot from './plots/Histogramuplot.svelte' | ||||||
|     import Histogram, { binsFromFootprint } from './plots/Histogram.svelte' |     import Pie from './plots/Pie.svelte' | ||||||
|  |     import { binsFromFootprint } from './plots/Histogram.svelte' | ||||||
|     import ScatterPlot from './plots/Scatter.svelte' |     import ScatterPlot from './plots/Scatter.svelte' | ||||||
|     import PlotTable from './PlotTable.svelte' |     import PlotTable from './PlotTable.svelte' | ||||||
|     import Roofline from './plots/Roofline.svelte' |     import Roofline from './plots/Roofline.svelte' | ||||||
| @@ -30,7 +31,7 @@ | |||||||
|     let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the |     let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the | ||||||
|     let jobFilters = []; |     let jobFilters = []; | ||||||
|     let rooflineMaxY; |     let rooflineMaxY; | ||||||
|     let colWidth; |     let colWidth1, colWidth2, colWidth3, colWidth4; | ||||||
|     let numBins = 50; |     let numBins = 50; | ||||||
|     let maxY = -1; |     let maxY = -1; | ||||||
|     const ccconfig = getContext('cc-config') |     const ccconfig = getContext('cc-config') | ||||||
| @@ -135,9 +136,8 @@ | |||||||
|         </Col> |         </Col> | ||||||
|     </Row> |     </Row> | ||||||
| {:else if $statsQuery.data} | {:else if $statsQuery.data} | ||||||
|     <Row> |     <Row cols={3} class="mb-4"> | ||||||
|         <div class="col-3" bind:clientWidth={colWidth}> |         <Col> | ||||||
|             <div style="height: 40%"> |  | ||||||
|             <Table> |             <Table> | ||||||
|                 <tr> |                 <tr> | ||||||
|                     <th scope="col">Total Jobs</th> |                     <th scope="col">Total Jobs</th> | ||||||
| @@ -156,23 +156,56 @@ | |||||||
|                     <td>{$statsQuery.data.stats[0].totalCoreHours}</td> |                     <td>{$statsQuery.data.stats[0].totalCoreHours}</td> | ||||||
|                 </tr> |                 </tr> | ||||||
|             </Table> |             </Table> | ||||||
|             </div> |         </Col> | ||||||
|             <div style="height: 60%;"> |         <Col> | ||||||
|  |             <div bind:clientWidth={colWidth1}> | ||||||
|  |             <h5>Top Users</h5> | ||||||
|             {#key $statsQuery.data.topUsers} |             {#key $statsQuery.data.topUsers} | ||||||
|                     <h4>Top Users (by node hours)</h4> |             <Pie | ||||||
|                     <Histogram |                 size={colWidth1} | ||||||
|                         width={colWidth - 25} height={300 * 0.5} small={true} |                 sliceLabel='Hours' | ||||||
|                         data={$statsQuery.data.topUsers.sort((a, b) => b.count - a.count).map(({ count }, idx) => ({ count, value: idx }))} |                 quantities={$statsQuery.data.topUsers.sort((a, b) => b.count - a.count).map((tu) => tu.count)} | ||||||
|                         label={(x) => x < $statsQuery.data.topUsers.length ? $statsQuery.data.topUsers[Math.floor(x)].name : 'No Users'}  |                 entities={$statsQuery.data.topUsers.sort((a, b) => b.count - a.count).map((tu) => tu.name)} | ||||||
|                         ylabel="Node Hours [h]"/> |             /> | ||||||
|             {/key} |             {/key} | ||||||
|             </div> |             </div> | ||||||
|  |         </Col> | ||||||
|  |         <Col> | ||||||
|  |             <Table> | ||||||
|  |                 <tr class="mb-2"><th>User Name</th><th>Node Hours</th></tr> | ||||||
|  |                 {#each $statsQuery.data.topUsers.sort((a, b) => b.count - a.count) as { name, count }} | ||||||
|  |                     <tr> | ||||||
|  |                         <th scope="col"><a href="/monitoring/user/{name}?cluster={cluster.name}">{name}</a></th> | ||||||
|  |                         <td>{count}</td> | ||||||
|  |                     </tr> | ||||||
|  |                 {/each} | ||||||
|  |             </Table> | ||||||
|  |         </Col> | ||||||
|  |     </Row> | ||||||
|  |     <Row cols={3} class="mb-2"> | ||||||
|  |         <Col> | ||||||
|  |             {#if $rooflineQuery.fetching} | ||||||
|  |                 <Spinner /> | ||||||
|  |             {:else if $rooflineQuery.error} | ||||||
|  |                 <Card body color="danger">{$rooflineQuery.error.message}</Card> | ||||||
|  |             {:else if $rooflineQuery.data && cluster} | ||||||
|  |                 <div bind:clientWidth={colWidth2}> | ||||||
|  |                 {#key $rooflineQuery.data} | ||||||
|  |                     <Roofline | ||||||
|  |                         width={colWidth2} height={300} | ||||||
|  |                         tiles={$rooflineQuery.data.rooflineHeatmap} | ||||||
|  |                         cluster={cluster.subClusters.length == 1 ? cluster.subClusters[0] : null} | ||||||
|  |                         maxY={rooflineMaxY} /> | ||||||
|  |                 {/key} | ||||||
|                 </div> |                 </div> | ||||||
|         <div class="col-3"> |             {/if} | ||||||
|  |         </Col> | ||||||
|  |         <Col> | ||||||
|  |             <div bind:clientWidth={colWidth3}> | ||||||
|             {#key $statsQuery.data.stats[0].histDuration} |             {#key $statsQuery.data.stats[0].histDuration} | ||||||
|                 <Histogramuplot |                 <Histogramuplot | ||||||
|  |                     width={colWidth3} height={300} | ||||||
|                     data={convert2uplot($statsQuery.data.stats[0].histDuration)} |                     data={convert2uplot($statsQuery.data.stats[0].histDuration)} | ||||||
|                     width={colWidth - 25} |  | ||||||
|                     title="Duration Distribution" |                     title="Duration Distribution" | ||||||
|                     xlabel="Current Runtimes" |                     xlabel="Current Runtimes" | ||||||
|                     xunit="Hours"  |                     xunit="Hours"  | ||||||
| @@ -180,11 +213,13 @@ | |||||||
|                     yunit="Jobs"/> |                     yunit="Jobs"/> | ||||||
|             {/key} |             {/key} | ||||||
|             </div> |             </div> | ||||||
|         <div class="col-3"> |         </Col> | ||||||
|  |         <Col> | ||||||
|  |             <div bind:clientWidth={colWidth4}> | ||||||
|             {#key $statsQuery.data.stats[0].histNumNodes} |             {#key $statsQuery.data.stats[0].histNumNodes} | ||||||
|                 <Histogramuplot |                 <Histogramuplot | ||||||
|  |                     width={colWidth4} height={300} | ||||||
|                     data={convert2uplot($statsQuery.data.stats[0].histNumNodes)} |                     data={convert2uplot($statsQuery.data.stats[0].histNumNodes)} | ||||||
|                     width={colWidth - 25} |  | ||||||
|                     title="Number of Nodes Distribution" |                     title="Number of Nodes Distribution" | ||||||
|                     xlabel="Allocated Nodes" |                     xlabel="Allocated Nodes" | ||||||
|                     xunit="Nodes" |                     xunit="Nodes" | ||||||
| @@ -192,25 +227,12 @@ | |||||||
|                     yunit="Jobs"/> |                     yunit="Jobs"/> | ||||||
|             {/key} |             {/key} | ||||||
|             </div> |             </div> | ||||||
|         <div class="col-3"> |         </Col> | ||||||
|             {#if $rooflineQuery.fetching} |  | ||||||
|                 <Spinner /> |  | ||||||
|             {:else if $rooflineQuery.error} |  | ||||||
|                 <Card body color="danger">{$rooflineQuery.error.message}</Card> |  | ||||||
|             {:else if $rooflineQuery.data && cluster} |  | ||||||
|                 {#key $rooflineQuery.data} |  | ||||||
|                     <Roofline |  | ||||||
|                         width={colWidth - 25} |  | ||||||
|                         tiles={$rooflineQuery.data.rooflineHeatmap} |  | ||||||
|                         cluster={cluster.subClusters.length == 1 ? cluster.subClusters[0] : null} |  | ||||||
|                         maxY={rooflineMaxY} /> |  | ||||||
|                 {/key} |  | ||||||
|             {/if} |  | ||||||
|         </div> |  | ||||||
|     </Row> |     </Row> | ||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| <br/> | <hr class="my-6"/> | ||||||
|  |  | ||||||
| {#if $footprintsQuery.error} | {#if $footprintsQuery.error} | ||||||
|     <Row> |     <Row> | ||||||
|         <Col> |         <Col> | ||||||
| @@ -284,7 +306,7 @@ | |||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| <style> | <style> | ||||||
|     h4 { |     h5 { | ||||||
|         text-align: center; |         text-align: center; | ||||||
|     } |     } | ||||||
| </style> | </style> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user