github.com/hernad/nomad@v1.6.112/ui/app/utils/resources-diffs.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import d3Format from 'd3-format'; 7 8 import { formatBytes, formatHertz } from 'nomad-ui/utils/units'; 9 10 const formatPercent = d3Format.format('+.0%'); 11 const sumAggregate = (total, val) => total + val; 12 13 export default class ResourcesDiffs { 14 constructor(model, multiplier, recommendations, excludedRecommendations) { 15 this.model = model; 16 this.multiplier = multiplier; 17 this.recommendations = recommendations; 18 this.excludedRecommendations = excludedRecommendations.filter((r) => 19 recommendations.includes(r) 20 ); 21 } 22 23 get cpu() { 24 const included = this.includedRecommendations.filterBy('resource', 'CPU'); 25 const excluded = this.excludedRecommendations.filterBy('resource', 'CPU'); 26 27 return new ResourceDiffs( 28 this.model.reservedCPU, 29 'reservedCPU', 30 'MHz', 31 this.multiplier, 32 included, 33 excluded 34 ); 35 } 36 37 get memory() { 38 const included = this.includedRecommendations.filterBy( 39 'resource', 40 'MemoryMB' 41 ); 42 const excluded = this.excludedRecommendations.filterBy( 43 'resource', 44 'MemoryMB' 45 ); 46 47 return new ResourceDiffs( 48 this.model.reservedMemory, 49 'reservedMemory', 50 'MiB', 51 this.multiplier, 52 included, 53 excluded 54 ); 55 } 56 57 get includedRecommendations() { 58 return this.recommendations.reject((r) => 59 this.excludedRecommendations.includes(r) 60 ); 61 } 62 } 63 64 class ResourceDiffs { 65 constructor( 66 base, 67 baseTaskPropertyName, 68 units, 69 multiplier, 70 includedRecommendations, 71 excludedRecommendations 72 ) { 73 this.base = base; 74 this.baseTaskPropertyName = baseTaskPropertyName; 75 this.units = units; 76 this.multiplier = multiplier; 77 this.included = includedRecommendations; 78 this.excluded = excludedRecommendations; 79 } 80 81 get recommended() { 82 if (this.included.length) { 83 return ( 84 this.included.mapBy('value').reduce(sumAggregate, 0) + 85 this.excluded 86 .mapBy(`task.${this.baseTaskPropertyName}`) 87 .reduce(sumAggregate, 0) 88 ); 89 } else { 90 return this.base; 91 } 92 } 93 94 get delta() { 95 return this.recommended - this.base; 96 } 97 98 get aggregateDiff() { 99 return this.delta * this.multiplier; 100 } 101 102 get absoluteAggregateDiff() { 103 const delta = Math.abs(this.aggregateDiff); 104 105 if (this.units === 'MiB') { 106 return formatBytes(delta, 'MiB'); 107 } else if (this.units === 'MHz') { 108 return formatHertz(delta, 'MHz'); 109 } else { 110 return `${delta} ${this.units}`; 111 } 112 } 113 114 get signedDiff() { 115 const delta = this.aggregateDiff; 116 return `${signForDelta(delta)}${this.absoluteAggregateDiff}`; 117 } 118 119 get percentDiff() { 120 return formatPercent(this.delta / this.base); 121 } 122 } 123 124 function signForDelta(delta) { 125 if (delta > 0) { 126 return '+'; 127 } else if (delta < 0) { 128 return '-'; 129 } 130 131 return ''; 132 }