Skip to content

Commit 919980e

Browse files
committed
Show hypervisor flavour stats.
1 parent b5e6c45 commit 919980e

File tree

8 files changed

+449
-197
lines changed

8 files changed

+449
-197
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import {Flavour} from "../../../core/graphql";
2+
3+
export type FlavourStats = {
4+
flavour: Flavour;
5+
used: number;
6+
available: number;
7+
}
8+
9+
export class HypervisorFlavoursChartData {
10+
11+
12+
private _options: any = {
13+
chart: {
14+
// plotBackgroundColor: null,
15+
// plotBorderWidth: null,
16+
plotShadow: false,
17+
type: 'bar',
18+
},
19+
title: {
20+
text: '',
21+
},
22+
xAxis: {
23+
categories: [],
24+
labels: {
25+
style: {
26+
fontSize: '11px',
27+
color: '#606060',
28+
},
29+
},
30+
gridLineWidth: 0,
31+
},
32+
yAxis: {
33+
title: {
34+
text: '',
35+
},
36+
labels: {
37+
enabled: false,
38+
},
39+
gridLineWidth: 0,
40+
},
41+
tooltip: {
42+
enabled: false,
43+
// backgroundColor: '#ffffff',
44+
// style: {
45+
// fontSize: '12px',
46+
// },
47+
// formatter: function () {
48+
// return `<span>${this.key}<br>${this.series.name}: <b>${this.y}</b></span>`;
49+
// }
50+
},
51+
plotOptions: {
52+
series: {
53+
borderRadius: 0,
54+
borderColor: '#cccccc',
55+
stacking: 'normal',
56+
groupPadding: 0,
57+
pointWidth: 15,
58+
dataLabels: {
59+
enabled: true,
60+
style: {
61+
color: '#ffffff',
62+
fontSize: '11px',
63+
fontWeight: 'normal',
64+
textOutline: 'none',
65+
}
66+
},
67+
},
68+
},
69+
legend: {
70+
enabled: false,
71+
},
72+
credits: {
73+
enabled: false,
74+
},
75+
series: [],
76+
}
77+
78+
get options(): any {
79+
return this._options;
80+
}
81+
82+
constructor(private flavourStats: FlavourStats[], private _enabled: boolean) {
83+
this._options.xAxis.categories = flavourStats.map(flavourStat => flavourStat.flavour.name);
84+
this._options.xAxis.labels.style.color = this._enabled ? '#606060' : '#c0c0c0';
85+
const usedData = flavourStats.map(flavourStat => {
86+
return {y: flavourStat.used}
87+
});
88+
const availableData = flavourStats.map(flavourStat => {
89+
return {y: flavourStat.available}
90+
});
91+
this._options.series = [
92+
{name: 'available', data: availableData, color: '#ffffff', dataLabels: {style: {color: this._enabled ? '#606060' : '#c0c0c0'}}},
93+
{name: 'used', data: usedData, color: this._enabled ? '#606060' : '#cccccc', dataLabels: {style: {color: '#ffffff'}}},
94+
]
95+
}
96+
97+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
2+
const hex2rgb = (hex) => {
3+
const r = parseInt(hex.slice(1, 3), 16);
4+
const g = parseInt(hex.slice(3, 5), 16);
5+
const b = parseInt(hex.slice(5, 7), 16);
6+
7+
return { r, g, b };
8+
}
9+
10+
const componentToHex = (c) => {
11+
const hex = c.toString(16);
12+
return hex.length == 1 ? "0" + hex : hex;
13+
}
14+
15+
const rgbToHex = (r, g, b) => {
16+
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
17+
}
18+
19+
export class HypervisorResourceChartData {
20+
21+
22+
private _options: any = {
23+
chart: {
24+
type: 'pie',
25+
},
26+
title: {
27+
text: '',
28+
},
29+
subtitle: {
30+
text: this.getSubtitle(),
31+
floating: true,
32+
useHTML: true,
33+
verticalAlign: 'middle',
34+
y: 12,
35+
},
36+
plotOptions: {
37+
series: {
38+
borderRadius: 0,
39+
allowPointSelect: false,
40+
// cursor: 'pointer',
41+
showInLegend: false,
42+
states: {
43+
hover: {
44+
enabled: false,
45+
}
46+
}
47+
},
48+
},
49+
credits: {
50+
enabled: false,
51+
},
52+
tooltip: {
53+
enabled: false,
54+
// style: {
55+
// backgroundColor: '#ffffff',
56+
// fontSize: '12px',
57+
// },
58+
// formatter: function () {
59+
// return `<span>${this.series.name}<br>${this.key}: <b>${this.y}</b></span>`;
60+
// },
61+
// useHTML: true,
62+
},
63+
series: [{
64+
type: 'pie',
65+
colorByPoint: true,
66+
allowPointSelect: false,
67+
innerSize: '75%',
68+
borderColor: '#cccccc',
69+
dataLabels: {
70+
enabled: false
71+
},
72+
data: [],
73+
}],
74+
}
75+
76+
get options(): any {
77+
return this._options;
78+
}
79+
80+
constructor(private _resource: string, private _total: number, private _used: number, private _enabled: boolean) {
81+
this._options.series[0] = {
82+
...this._options.series[0],
83+
name: this._resource,
84+
data: [
85+
{ name: 'used', y: Math.floor(this._used), color: this.getSeverityColour(this._used / this._total)},
86+
{ name: 'available', y: Math.floor(this._total - this._used), color: '#ffffff'},
87+
]
88+
}
89+
this._options.series[0].borderColor = this._enabled ? '#cccccc' : '#dddddd';
90+
}
91+
92+
private getSubtitle(): string {
93+
const extraStyle = this._enabled ? '' : 'chart-title-container__disabled';
94+
return `
95+
<div class="chart-title-container ${extraStyle}">
96+
<div class="chart-title-main">${this._resource}</div>
97+
<div class="chart-title-sub">${Math.floor(this._used)} / ${Math.floor(this._total)}</div>
98+
</div>
99+
`;
100+
}
101+
102+
private getSeverityColour(value: number): string {
103+
if (!this._enabled) {
104+
return '#cccccc';
105+
}
106+
107+
value = Math.max(0.0, Math.min(value, 1.0));
108+
109+
const colours = [
110+
hex2rgb('#00a65a'),
111+
hex2rgb('#00a65a'),
112+
hex2rgb('#00a65a'),
113+
hex2rgb('#ffcc00'),
114+
hex2rgb('#ff9900'),
115+
hex2rgb('#dd4b39'),
116+
hex2rgb('#ff0000'),
117+
]
118+
119+
const i1 = Math.floor((colours.length - 1) * value);
120+
const i2 = Math.ceil((colours.length - 1) * value);
121+
122+
const colourStep = 1.0 / (colours.length - 1);
123+
const diff = value - i1 * colourStep;
124+
125+
const colour = {
126+
r: Math.floor(colours[i1].r + diff * (colours[i2].r - colours[i1].r)),
127+
g: Math.floor(colours[i1].g + diff * (colours[i2].g - colours[i1].g)),
128+
b: Math.floor(colours[i1].b + diff * (colours[i2].b - colours[i1].b)),
129+
}
130+
131+
return rgbToHex(colour.r, colour.g, colour.b);
132+
}
133+
134+
}

src/app/admin/components/hypervisors/hypervisor.component.html

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,51 @@
44
{{hypervisor.hostname}}
55
</div>
66
<div class="hypervisor__content">
7-
Server count: {{hypervisor.allocations.length}}
8-
</div>
9-
<div class="hypervisor-chart-container">
10-
<div *ngIf="vcpuChartData" class="hypervisor-chart-holder">
11-
<highcharts-chart [options]="vcpuChartData.options"
12-
[Highcharts]="highcharts"
13-
class="hypervisor-chart">
14-
</highcharts-chart>
15-
</div>
16-
<div *ngIf="ramChartData" class="hypervisor-chart-holder">
17-
<highcharts-chart [options]="ramChartData.options"
18-
[Highcharts]="highcharts"
19-
class="hypervisor-chart">
20-
</highcharts-chart>
7+
8+
<div class="hypervisor-resources">
9+
<div class="hypervisor-resources__title">
10+
All resources:
11+
</div>
12+
<div class="hypervisor-resource-chart-container">
13+
<div *ngIf="vcpuChartData" class="hypervisor-resource-chart-holder">
14+
<highcharts-chart [options]="vcpuChartData.options"
15+
[Highcharts]="highcharts"
16+
class="hypervisor-resource-chart">
17+
</highcharts-chart>
18+
</div>
19+
<div *ngIf="ramChartData" class="hypervisor-resource-chart-holder">
20+
<highcharts-chart [options]="ramChartData.options"
21+
[Highcharts]="highcharts"
22+
class="hypervisor-resource-chart">
23+
</highcharts-chart>
24+
</div>
25+
<div *ngFor="let chartData of customChartData" class="hypervisor-resource-chart-holder">
26+
<highcharts-chart [options]="chartData.options"
27+
[Highcharts]="highcharts"
28+
class="hypervisor-resource-chart">
29+
</highcharts-chart>
30+
</div>
31+
</div>
2132
</div>
22-
<div *ngFor="let chartData of customChartData" class="hypervisor-chart-holder">
23-
<highcharts-chart [options]="chartData.options"
24-
[Highcharts]="highcharts"
25-
class="hypervisor-chart">
26-
</highcharts-chart>
33+
34+
<div class="hypervisor-flavours">
35+
<div class="hypervisor-flavours__title">
36+
Resource usage:
37+
</div>
38+
<div style="display: flex; flex-direction: row; justify-content: flex-start; align-items: center; column-gap: 12px">
39+
<div>
40+
Server count: {{hypervisor.allocations?.length}}
41+
</div>
42+
<div>
43+
Instance count: {{instanceCount}}
44+
</div>
45+
</div>
46+
<div *ngIf="flavoursChartData" class="hypervisor-flavours-chart-holder">
47+
<highcharts-chart [options]="flavoursChartData.options"
48+
[Highcharts]="highcharts"
49+
class="hypervisor-flavours-chart">
50+
</highcharts-chart>
51+
</div>
2752
</div>
28-
</div>
2953
</div>
3054

src/app/admin/components/hypervisors/hypervisor.component.scss

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
.hypervisor {
2-
width: 320px;
32
min-height: 300px;
43
height: 100%;
54
display: flex;
@@ -16,9 +15,12 @@
1615
}
1716

1817
&__content {
19-
font-weight: 300;
20-
font-size: 11pt;
21-
line-height: 30px;
18+
width: 640px;
19+
20+
display: flex;
21+
flex-direction: row;
22+
justify-content: space-evenly;
23+
align-items: flex-start;
2224
}
2325

2426
&__disabled {
@@ -52,19 +54,33 @@
5254
border-right-color: #f4f4f4;
5355
}
5456

55-
.hypervisor-chart-container {
57+
.hypervisor-resources {
58+
width: 300px;
59+
display: flex;
60+
flex-direction: column;
61+
justify-content: flex-start;
62+
align-items: center;
63+
font-size: 12px;
64+
65+
&__title {
66+
font-size: 14px;
67+
font-weight: 500;
68+
}
69+
}
70+
71+
.hypervisor-resource-chart-container {
5672
display: flex;
5773
flex-direction: row;
5874
justify-content: center;
5975
align-items: center;
6076
flex-wrap: wrap;
6177
}
6278

63-
.hypervisor-chart-holder {
79+
.hypervisor-resource-chart-holder {
6480
width: 140px;
6581
}
6682

67-
.hypervisor-chart {
83+
.hypervisor-resource-chart {
6884
display: block;
6985
height: 140px;
7086

@@ -75,6 +91,7 @@
7591
align-items: center;
7692
font-size: 9pt;
7793
color: #606060;
94+
z-index: 0;
7895

7996
&__disabled {
8097
color: #c0c0c0;
@@ -87,4 +104,25 @@
87104
}
88105
}
89106

107+
.hypervisor-flavours {
108+
display: flex;
109+
flex-direction: column;
110+
justify-content: flex-start;
111+
align-items: center;
112+
font-size: 12px;
113+
114+
&__title {
115+
font-size: 14px;
116+
font-weight: 500;
117+
}
118+
}
119+
120+
.hypervisor-flavours-chart-holder {
121+
width: 300px;
122+
}
123+
124+
.hypervisor-flavours-chart {
125+
display: block;
126+
height: 220px;
127+
}
90128

0 commit comments

Comments
 (0)