Building a 3D Data Center with WebGL (Three.js) – Standard Room Edition
Introduction
Data centers today are mainly divided in to two categories: standard data centers where cabinets are arranged in an XY grid, and micro-module data centers composed of grouped cabinets. This article focuses on the visual representation of a standard data center, allowing real-time 3D data viewing directly in a browser.
Feature Summary: Standard 3D data center construction, real-time monitoring of cabinets, servers, and ports with linked data display, dynamic addition of cabinets, server mounting and unmounting, visual presentation of environmental data (temperature/humidity heatmaps, access control, power distribution, cabling), and alarm display.
Technical Challenges:
-
Efficient and accurate modeling of a real-world data center:
- Solution: Encapsulate reusable code models to quickly and efficiently construct the data center.
-
Integrating real-time data:
- Solution: Use a single request for initial data, then update only changed data via a subscription/notification mechanism.
-
Smooth transitions between different scenes without lag or delay:
- Solution: Employ a state machine strategy to control state changes and rollbacks, managing transitions effectively.
-
Managing loading speed, browser memory, and frame rate for scenes with tens of thousands of servers:
- Solution: Use code-based models to reduce memory footprint. Implement a tile strategy to load only what is visible, minimizing browser draw calls and ensuring stable frame rates.
Significance of 3D Data Visualization:
- Practicality: Intuitively and quickly display data, raise alarms, and rapidly locate problems, saving significant troubleshooting time.
- Cost Management: Provide leaders and executives with the most efficient management tools.
- De-professionalization: Make complex professional systems understandable and operable for a wider audience.
- Technology: Complex systems need intuitive displays; complicated things need simple descriptions. Visualization addresses this need.
- Presentation: A 3D data dashboard enhances a company's image, demonstrating capability and sophistication to clients.
- Convenience: Directly view the 3D data center in a web browser on a computer or mobile device for quick and easy access.
Feature Demonstrations
1. Data Center Modeling
a. Standard Data Center
Data Center Code Model:
var models = [
{ // Floor
"show": true,
"uuid": "",
"name": "DCR01_floor",
"objType": "cube2",
"length": 2350+400,
"width": 2000+400,
"height": 10,
"x": 0,
"y": 0,
"z": 0,
"style": {
"skinColor": 16777215,
"skin": {
"skin_up": {
"skinColor": 16777215,
"side": 1,
"opacity": 1,
"imgurl": "../img/3dImg/wall/floor5.jpg",
"repeatx": true,
"width": 20,
"repeaty": true,
"height": 30
},
// ... other sides
}
},
// ... other properties
},
// ... Air conditioner, walls, doors, etc.
];
// Adding cabinets dynamically
for (var i = 1; i <= 6; i++) {
var showface = -1;
if (i == 6) { showface = 0; }
var cabModel = getCabinetModel(
"DCR01_cab_A_" + i,
{ x: 1, y: 1, z: 1 },
{ "x": 475, "y": 210, "z": -60 + (i - 1) * 155 },
[{ "direction": "y", "degree": Math.PI }],
showface,
roomName
);
models.push(cabModel);
var cabinetData = wtserverAPI.CabinetBoxHandlerCacheData["c_" + roomName + "_" + "DCR01_cab_A_" + i];
var deviceCount = cabinetData && cabinetData.devChildren ? cabinetData.devChildren.length : 0;
if (deviceCount > 0) {
var serverGroup = getServerModel(
"DCR01_cab_A_" + i + "_sGroup",
0,
{ "x": 475, "y": 210, "z": -60 + (i - 1) * 155 },
{ x: 1, y: 1, z: 1 },
Math.PI
);
models.push(serverGroup);
}
}
// ... similar loops for other cabinet rows
// Merge models for performance optimization
var cabinetNames = [];
for (var i = 1; i <= 27; i++) { cabinetNames.push("DCR01_cab_A_" + i); }
models.push({ show: true, objType: "MergeModels", oldObjNames: cabinetNames });
b. Irregularly Shaped Data Center
Model of a complex enviroment:
Zoomed-in view of a local model:
Picture-in-picture affect showing video or desktop within the 3D model:
c. Micro-module Data Center (detailed in next article)
d. Combined Data Center (micro-modules and standard cabinets)
2. Hover Over Cabinet to Show Summary
3. Double-Click Cabinet to Show Details
4. Open Cabinet Door to View Server Details
5. Cabinet Utilization Rate Display
Code Implementation:
ModelBussiness.prototype.showSpaceRate = function () {
var _this = this;
var cabinetNames = wtserverAPI.cabNames;
if (_this.rateSpaceState == 0) {
_this.rateSpaceState = 1;
// UI logic
_this.hideAllCabinet("tempKey", function () {
if (_this.rateSpaceCubeNames.length <= 0) {
// Fetch utilization data from server and create rate cubes
wtserverAPI.CabRate(modelBussiness.roomName, function (result) {
// Process result and create 3D visualization
for (var i = 0; i < cabinetNames.length; i++) {
var targetObj = WT3DObj.commonFunc.findObject(cabinetNames[i]);
var rateValue = 0; // derived from result
var style = { borderColor: 0xffffff, innerColor: 0x6495ed, innerOprity: 1, outColor: 0xffffff, outOprity: 0.1 };
_this.commonFunc.createRateCube(cabinetNames[i],
{ x: 160, y: 380, z: 140 },
{ x: targetObj.position.x, y: targetObj.position.y, z: targetObj.position.z },
{ x: 0, y: 0, z: 0 },
rateValue,
style, { timelong: 1000 });
}
}, function (err) {
// Error handling
});
} else {
// Use cached data
}
});
} else {
_this.hideSpaceRate();
// Restore original cabinet visibility
}
}
6. Available Space Display
Code Implementation:
MSS.prototype.showUsageMap_old = function () {
var _this = this;
if (_this.agesSpaceState == 0) {
_this.agesSpaceState = 1;
// UI logic
_this.hideAllCabinet("tempKey", function () {
if (_this.agesSpaceCubeNames.length <= 0) {
// Fetch free space data from server
wtserverAPI.FreeSpace(modelBussiness.roomName, function (result) {
// Process result and create usage cubes
for (var i = 1; i <= 49; i++) {
var targetObj = WT3DObj.commonFunc.findObject(modelBussiness.roomName + "_cab_A_" + i);
var ageValue = []; // derived from result
var style = { borderColor: 0x444444, outColor: 0xffffff, outOprity: 0.1 };
_this.commonFunc.createUseageCube(modelBussiness.roomName + "_cab_A_" + i,
{ x: 160, y: 380, z: 140 },
{ x: targetObj.position.x, y: targetObj.position.y, z: targetObj.position.z },
{ x: 0, y: 0, z: 0 },
ageValue,
style, { timelong: 1000 }, i);
}
// Similar loop for B cabinets
}, function () {
layer.msg("Data interface error!");
});
} else {
// Use cached data
}
});
} else {
this.hideUsageSpaceRate();
// Restore original cabinet visibility
}
}
7. Cable Management Display
8. Temperature Heatmap Display
9. Alarm Cabinet Display
Smoke alarm simulation:
10. Air Conditioning Airflow
Data Integration Code Implementation
function WTServerAPI() { }
WTServerAPI.prototype.init = function () {
this.alarmColors = {
"Disaster": "0xff0000",
"Warning": "0xff0000",
"Critical": "0xffff00",
"Minor": "0x00ff00",
"Info": "0x00ffff",
}
}
WTServerAPI.prototype.getAlarmColor = function (level) {
return this.alarmColors[level] ? this.alarmColors[level] : "0xff0000";
}
WTServerAPI.prototype.roomId = function (key) {
var keyValues = {
ITC: "c12d7373-a6db-4a3f-96a0-f1a851a8825d",
PCR: "dd01271f-7129-4ba1-afcb-fb2dd9017db9",
DCR01: "b243a046-31f5-4ba4-891c-bd4e8368c0d9",
DCR02: "d8de327b-6b11-4a18-b1d8-168ce0c06d4f",
DCR03: "9c26ffd0-e9b1-40bb-8437-a74336c36d26",
DCR04: "00a33071-252a-423e-891d-2d836ae23d00"
};
return keyValues[key];
}
// SignalR connection for real-time alarms
WTServerAPI.prototype.startSignalRServer = function (callback) {
$.getScript(wtserverAPI.SignalrHubs, function () {
var chat = $.connection.signalRHub;
chat.client.Room3DAlert = function (res) {
if (callback) { callback(res); }
};
$.connection.hub.start().done(function () { /* connected */ });
});
}
WTServerAPI.prototype.SignalrMsg = function (res) {
var msg = JSON.parse(res);
if (msg && msg.msgType == "Room3DAlert") {
if (modelBussiness) { modelBussiness.alarmServer(msg.message); }
}
}
// ... other API methods for cabinet info, ports, utilization, etc.
var wtserverAPI = null;
Logic Control Code
var WT3DModel;
function threeStart(_height, roomName, dataFunc) {
WT3DModel = new WT3D();
var initOption = {
antialias: true,
loadSyn: true,
showHelpGrid: false,
clearCoolr: 0x4068b0,
clearColorOp: 0,
};
var Aobjects = {
objects: dataFunc(roomName),
// Animation definitions
// Event definitions (double-click, mouse down, etc.)
// Button definitions
};
// Preload images
Aobjects.imageList = [];
// ... image extraction logic
WT3DModel.initWT3D('canvas-frame', initOption, Aobjects);
WT3DModel.start();
}
// Door open/close animation functions
function openCabinetDoor(obj, cmd, func) { /* ... */ }
function openRightDoor(obj, func, cmd) { /* ... */ }
function openLeftDoor(obj, func, cmd) { /* ... */ }
Preview of Next Article
The next article will focus on the implementation and features of micro-module data centers.
Related Articles
- How to build a 3D warehouse with WebGL (Three.js) – Lesson 1
- How to build a 3D warehouse with WebGL (Three.js) – Lesson 2
- Building a 3D building with WebGL (Three.js) – Lesson 3
- Building a 3D smart park with WebGL (Three.js) – Lesson 4
- How to build an irregular 3D building model with WebGL (Three.js)