新版状态页面

This commit is contained in:
2024-04-26 15:06:21 +08:00
parent 5100ca6c77
commit f69844717f
121 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,19 @@
.data-storage {
display: none;
}
body {
background-repeat: repeat-y;
background-size: cover;
background-position: center;
text-shadow: 1px 1px 2px black;
margin: 20px;
}
.info-box {
border-radius: 30px;
padding: 30px;
backdrop-filter: blur(10px);
background-color: rgba(0, 0, 0, 0.5);
margin-bottom: 20px;
}

View File

@ -0,0 +1,76 @@
/*MiSans*/
@font-face {
font-family: 'MiSans';
src: url('../fonts/MiSans/MiSans-Light.woff2') format('woff2');
font-weight: 200;
}
@font-face {
font-family: 'MiSans';
src: url('../fonts/MiSans/MiSans-Normal.woff2') format('woff2');
font-weight: 400;
}
@font-face {
font-family: 'MiSans';
src: url('../fonts/MiSans/MiSans-Semibold.woff2') format('woff2');
font-weight: 500;
}
@font-face {
font-family: 'MiSans';
src: url('../fonts/MiSans/MiSans-Bold.woff2') format('woff2');
font-weight: 700;
}
@font-face {
font-family: 'MiSans';
src: url('../fonts/MiSans/MiSans-Heavy.woff2') format('woff2');
font-weight: 900;
}
/*MapleMono*/
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-Light.woff2') format('woff2');
font-weight: 200;
}
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-LightItalic.woff2') format('woff2');
font-weight: 200;
font-style: italic;
}
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-Regular.woff2') format('woff2');
font-weight: 400;
}
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-Italic.woff2') format('woff2');
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-Bold.woff2') format('woff2');
font-weight: 700;
}
@font-face {
font-family: 'MapleMono';
src: url('../fonts/MapleMono/MapleMono-BoldItalic.woff2') format('woff2');
font-weight: 700;
font-style: italic;
}
* {
font-family: 'MapleMono', 'MiSans', sans-serif;
}

View File

@ -0,0 +1,130 @@
:root {
--main-text-color: #fff;
--sub-text-color: #bbb;
--tip-text-color: #888;
--device-info-width: 240px;
}
.bot-info {
display: flex;
height: 200px;
}
.bot-icon {
display: flex;
height: 100%;
aspect-ratio: 1;
align-items: center;
justify-content: center;
margin-right: 20px;
}
.bot-icon-img {
border-radius: 50%;
height: 100%;
width: 100%;
background-color: white;
}
.bot-name {
color: var(--main-text-color);
display: flex;
font-size: 40px;
flex-direction: column;
justify-content: center;
}
.bot-tag {
white-space: nowrap;
color: var(--sub-text-color);
font-size: 27px;
font-weight: 700;
line-height: 1.6;
}
.bot-tag[suffix="1"]::after {
content: " | ";
display: inline-block;
margin: 0 5px;
height: 30%;
line-height: 50%;
color: var(--tip-text-color);
}
/*修改bot-info 下hr样式*/
.bot-info hr {
border: 0;
height: 4px;
background: var(--tip-text-color);
margin: 10px 0;
width: 100%;
}
#hardware-info {
display: flex;
justify-content: space-evenly;
}
.device-info {
max-width: 30%;
}
.device-chart {
display: flex;
height: var(--device-info-width);
width: var(--device-info-width);
margin-bottom: 20px;
justify-content: center;
}
.device-tags {
text-align: center;
color: var(--sub-text-color);
font-size: 24px;
max-width: var(--device-info-width);
word-wrap: break-word;
}
.disk-info {
display: flex;
position: relative;
width: 100%;
height: 60px;
background-color: #ffffff44;
border-radius: 30px;
align-items: center;
}
.disk-usage {
background-color: #a2d8f4;
height: 100%;
border-radius: 30px;
position: absolute;
z-index: 1;
}
.disk-title {
position: absolute;
color: var(--main-text-color);
font-size: 24px;
margin-bottom: 10px;
margin-left: 20px;
text-align: left;
z-index: 2;
}
#motto-text {
font-size: 36px;
word-wrap: break-word;
color: var(--main-text-color);
text-align: center;
margin: 30px 0 10px 0;
}
#motto-from {
font-size: 24px;
font-style: italic;
color: var(--sub-text-color);
text-align: right;
}

View File

@ -0,0 +1,101 @@
body {
background-repeat: repeat-y;
background-size: cover;
background-position: center;
color: white;
/ / 10px10px0px / / margin: 24 px;
margin: 20px;
}
.info-box {
border-radius: 30px;
padding: 30px;
backdrop-filter: blur(10px);
background-color: rgba(0, 0, 0, 0.3);
margin-bottom: 20px;
}
.pie-chart {
height: 240px;
width: 240px;
margin-bottom: 20px;
}
.pie-info {
margin: 0 40px;
align-items: center;
}
.bot-info {
align-items: center;
display: flex;
}
#hardware-info {
justify-content: center;
text-align: center;
display: flex;
}
#disks-info {
flex-wrap: wrap;
justify-content: center;
}
#motto-info {
margin-bottom: 0;
text-align: center;
white-space: pre-wrap;
}
.bot-icon {
border-radius: 50%;
height: 200px;
background-color: white;
}
.bot-name, .bot-tag {
margin-left: 20px;
}
.bot-name {
font-size: 42px;
font-weight: bold;
}
.bot-tag {
margin-top: 10px;
}
.chart-label {
font-size: 24px;
max-width: 240px;
}
.tag {
font-size: 32px;
font-weight: 700;
font-style: italic;
}
.tag[suffix="1"]::after {
content: " | ";
display: inline-block;
margin: 0 5px;
height: 50%;
line-height: 50%;
color: #ccc;
}
.motto-text {
font-size: 36px;
color: #fff;
}
.motto-author {
font-size: 30px;
font-style: italic;
color: #ccc;
}

View File

@ -0,0 +1,83 @@
#weather-info {
color: white;
/*justify-content: center;*/
/*align-items: center;*/
/*align-content: center;*/
}
#main-info {
display: flex;
justify-content: center;
align-items: center;
}
#time {
font-size: 25px;
font-weight: bold;
font-style: italic;
text-align: right;
color: #aaa;
}
#adm {
font-size: 30px;
font-weight: bold;
text-align: center;
color: #aaa;
}
#city {
margin-top: 20px;
font-size: 70px;
font-weight: bold;
text-align: center;
}
#temperature {
display: flex;
align-items: baseline;
}
#temperature-now {
font-size: 70px;
font-weight: bold;
}
#temperature-range {
font-size: 40px;
font-weight: bold;
color: #aaa;
}
#description {
font-size: 50px;
font-weight: bold;
}
#aqi {
height: 50px;
display: flex;
border-radius: 60px;
padding: 5px;
font-size: 40px;
text-align: center;
align-content: center;
align-items: center;
justify-content: center;
}
#aqi-dot {
height: 80%;
aspect-ratio: 1 / 1;
border-radius: 50%;
background-color: #aaa;
margin-right: 20px;
}
.main-icon {
width: 240px;
height: 240px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,11 @@
const bgs = [
"bg1.png",
"bg3.png",
"bg4.png",
"bg5.png",
"bg6.png",
"bg7.png",
"bg9.png",
]
// 随机选择背景图片
document.body.style.backgroundImage = `url(./img/${bgs[Math.floor(Math.random() * bgs.length)]})`;

View File

@ -0,0 +1,113 @@
// 存放格言
const mottos = [
{
"text": "同是天涯沦落人,相逢何必曾相识。",
"author": "白居易",
"source": "《琵琶行》"
},
{
"text": "海内存知己,天涯若比邻。",
"author": "王勃",
"source": "《送杜少府之任蜀州》"
},
{
"text": "银烛秋光冷画屏,轻罗小扇扑流萤。",
"author": "陆游",
"source": "《秋夕》"
},
{
"text": "明月几时有,把酒问青天。",
"author": "苏轼",
"source": "《水调歌头》"
},
{
"text": "人生自古谁无死,留取丹心照汗青。",
"author": "文天祥",
"source": "《过零丁洋》"
},
{
"text": "山重水复疑无路,柳暗花明又一村。",
"author": "陆游",
"source": "《游山西村》"
},
{
"text": "逸一时,误一世,逸久逸久罢已龄",
"author": "田所浩二",
"source": "《仲夏夜之淫梦》"
},
{
"text": "你知道吗轻雪只能在Python3.10以上的版本中使用。",
"author": "SnowyKami",
"source": "轻雪文档"
},
{
"text": "你知道吗,轻雪可以通过自定义资源包来扩展主题和语言",
"author": "SnowyKami",
"source": "轻雪文档"
},
{
"text": "你知道吗,轻雪交流群的群号是 775840726",
"author": "SnowyKami",
"source": "轻雪文档"
},
{
"text": "你知道吗轻雪运行过程中会启动一个node.js运行环境",
"author": "SnowyKami",
"source": "轻雪文档"
},
{
"text": "你知道吗轻雪的主题是基于HTML5开发的",
"author": "SnowyKami",
"source": "轻雪文档"
},
{
"text": "路漫漫其修远兮,吾将上下而求索。",
"author": "屈原",
"source": "《离骚》"
},
{
"text": "千里之行,始于足下。",
"author": "老子",
"source": "《道德经》"
},
{
"text": "读书破万卷,下笔如有神。",
"author": "杜甫",
"source": "《奉赠韦左丞丈二十韵》"
},
{
"text": "不登高山,不知天之高也;不临深溪,不知地之厚也。",
"author": "荀子",
"source": "《劝学》"
},
{
"text": "知之者不如好之者,好之者不如乐之者。",
"author": "孔子",
"source": "《论语》"
},
{
"text": "天行健,君子以自强不息;地势坤,君子以厚德载物。",
"source": "《易经》",
"author": ""
},
{
"text": "书山有路勤为径,学海无涯苦作舟。",
"author": "韩愈",
"source": "《读书有感》"
},
{
"text": "前事不忘,后事之师。",
"author": "孔子",
"source": "《论语》"
},
{
"text": "志当存高远,若樽俎断绝。",
"author": "陶渊明",
"source": "《饮酒》"
},
{
"text": "不以物喜,不以己悲。",
"author": "傅子",
"source": "《傅子》"
}
]

View File

@ -0,0 +1,295 @@
const data = JSON.parse(document.getElementById('data').innerText);
const bot_data = data['bot']; // 机器人数据
const hardwareData = data['hardware']; // 硬件数据
const liteyukiData = data['liteyuki']; // LiteYuki数据
const localData = data['localization']; // 本地化语言数据
/**
* 创建CPU/内存/交换饼图
* @param title
* @param {Array<{name: string, value: number}>} data 数据
*/
function createPieChartOption(title, data) {
// data为各项占比列表
return {
animation: false,
title: {
text: title,
left: 'center',
top: 'center',
textStyle: {
color: '#fff',
fontSize: 30,
lineHeight: 36
}
},
tooltip: {
show: true,
trigger: 'item',
backgroundColor: '#fff',
},
color: data.length === 3 ? ['#00a6ff', '#a2d8f4', "#ffffff44"] : ['#a2d8f4', '#ffffff44'],
series: [
{
name: 'info',
type: 'pie',
radius: ['80%', '100%'],
center: ['50%', '50%'],
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
}
},
emphasis: {
label: {
show: true,
textStyle: {
fontSize: '50',
fontWeight: 'bold'
}
}
}
},
data: data
}
]
}
}
function convertSize(size, precision = 2, addUnit = true, suffix = " XiB") {
let isNegative = size < 0;
size = Math.abs(size);
let units = ["", "K", "M", "G", "T", "P", "E", "Z"];
let unit = "";
for (let i = 0; i < units.length; i++) {
if (size < 1024) {
unit = units[i];
break;
}
size /= 1024;
}
if (isNegative) {
size = -size;
}
if (addUnit) {
return size.toFixed(precision) + suffix.replace('X', unit);
} else {
return size;
}
}
/**
* 创建磁盘用量柱状图
* @param title
* @param percent 数据
*/
function createBarChart(title, percent) {
// percent为百分比最大值为100
let diskDiv = document.createElement('div')
diskDiv.setAttribute('class', 'disk-info')
diskDiv.style.marginBottom = '20px'
diskDiv.innerHTML = `
<div class="disk-title">${title}</div>
<div class="disk-usage" style="width: ${percent}%"></div>
`
return diskDiv
}
function secondsToTextTime(seconds) {
let days = Math.floor(seconds / 86400)
let hours = Math.floor((seconds % 86400) / 3600)
let minutes = Math.floor((seconds % 3600) / 60)
let seconds_ = Math.floor(seconds % 60)
return `${days}${localData['days']} ${hours}${localData['hours']} ${minutes}${localData['minutes']} ${seconds_}${localData['seconds']}`
}
// 主函数
function main() {
// 添加机器人信息
bot_data['bots'].forEach(
(bot) => {
let botInfoDiv = document.importNode(document.getElementById('bot-template').content, true) // 复制模板
// 设置机器人信息
botInfoDiv.className = 'info-box bot-info'
botInfoDiv.querySelector('.bot-icon-img').setAttribute('src', bot['icon'])
botInfoDiv.querySelector('.bot-name').innerText = bot['name']
let tagArray = [
bot['protocol_name'],
bot['app_name'],
`${localData['groups']} ${bot['groups']}`,
`${localData['friends']} ${bot['friends']}`,
`${localData['message_sent']} ${bot['message_sent']}`,
`${localData['message_received']} ${bot['message_received']}`,
]
// 添加一些标签
tagArray.forEach(
(tag, index) => {
let tagSpan = document.createElement('span')
tagSpan.className = 'bot-tag'
tagSpan.innerText = tag
// 给最后一个标签不添加后缀
tagSpan.setAttribute('suffix', index === tagArray.length - 1 ? '0' : '1')
botInfoDiv.querySelector('.bot-tags').appendChild(tagSpan)
}
)
document.body.insertBefore(botInfoDiv, document.getElementById('hardware-info')) // 插入对象
}
)
// 添加轻雪信息
let liteyukiInfoDiv = document.importNode(document.getElementById('bot-template').content, true) // 复制模板
liteyukiInfoDiv.className = 'info-box bot-info'
liteyukiInfoDiv.querySelector('.bot-icon-img').setAttribute('src', './img/liteyuki.png')
liteyukiInfoDiv.querySelector('.bot-name').innerText = liteyukiData['name']
let tagArray = [
`Liteyuki ${liteyukiData['version']}`,
`Nonebot ${liteyukiData['nonebot']}`,
liteyukiData['python'],
liteyukiData['system'],
`${localData['plugins']} ${liteyukiData['plugins']}`,
`${localData['bots']} ${liteyukiData['bots']}`,
`${localData['runtime']} ${secondsToTextTime(liteyukiData['runtime'])}`,
]
tagArray.forEach(
(tag, index) => {
let tagSpan = document.createElement('span')
tagSpan.className = 'bot-tag'
tagSpan.innerText = tag
// 给最后一个标签不添加后缀
tagSpan.setAttribute('suffix', index === tagArray.length - 1 ? '0' : '1')
liteyukiInfoDiv.querySelector('.bot-tags').appendChild(tagSpan)
}
)
document.body.insertBefore(liteyukiInfoDiv, document.getElementById('hardware-info')) // 插入对象
// 添加硬件信息
const cpuData = hardwareData['cpu']
const memData = hardwareData['memory']
const swapData = hardwareData['swap']
const cpuTagArray = [
cpuData['name'],
`${cpuData['cores']}${localData['cores']} ${cpuData['threads']}${localData['threads']}`,
`${(cpuData['freq'] / 1000).toFixed(2)}GHz`
]
const memTagArray = [
`${localData['process']} ${convertSize(memData['usedProcess'])}`,
`${localData['used']} ${convertSize(memData['used'])}`,
`${localData['free']} ${convertSize(memData['free'])}`,
`${localData['total']} ${convertSize(memData['total'])}`
]
const swapTagArray = [
`${localData['used']} ${convertSize(swapData['used'])}`,
`${localData['free']} ${convertSize(swapData['free'])}`,
`${localData['total']} ${convertSize(swapData['total'])}`
]
let cpuDeviceInfoDiv = document.importNode(document.getElementById('device-info').content, true)
let memDeviceInfoDiv = document.importNode(document.getElementById('device-info').content, true)
let swapDeviceInfoDiv = document.importNode(document.getElementById('device-info').content, true)
cpuDeviceInfoDiv.querySelector('.device-info').setAttribute('id', 'cpu-info')
memDeviceInfoDiv.querySelector('.device-info').setAttribute('id', 'mem-info')
swapDeviceInfoDiv.querySelector('.device-info').setAttribute('id', 'swap-info')
cpuDeviceInfoDiv.querySelector('.device-chart').setAttribute('id', 'cpu-chart')
memDeviceInfoDiv.querySelector('.device-chart').setAttribute('id', 'mem-chart')
swapDeviceInfoDiv.querySelector('.device-chart').setAttribute('id', 'swap-chart')
let devices = {
'cpu': cpuDeviceInfoDiv,
'mem': memDeviceInfoDiv,
'swap': swapDeviceInfoDiv
}
// 遍历添加标签
for (let device in devices) {
let tagArray = []
switch (device) {
case 'cpu':
tagArray = cpuTagArray
break
case 'mem':
tagArray = memTagArray
break
case 'swap':
tagArray = swapTagArray
break
}
tagArray.forEach(
(tag, index) => {
let tagDiv = document.createElement('div')
tagDiv.className = 'device-tag'
tagDiv.innerText = tag
// 给最后一个标签不添加后缀
tagDiv.setAttribute('suffix', index === tagArray.length - 1 ? '0' : '1')
devices[device].querySelector('.device-tags').appendChild(tagDiv)
}
)
}
// 插入
document.getElementById('hardware-info').appendChild(cpuDeviceInfoDiv)
document.getElementById('hardware-info').appendChild(memDeviceInfoDiv)
document.getElementById('hardware-info').appendChild(swapDeviceInfoDiv)
let cpuChart = echarts.init(document.getElementById('cpu-chart'))
let memChart = echarts.init(document.getElementById('mem-chart'))
let swapChart = echarts.init(document.getElementById('swap-chart'))
cpuChart.setOption(createPieChartOption(`${localData['cpu']}\n${cpuData['percent'].toFixed(1)}%`, [
{name: 'used', value: cpuData['percent']},
{name: 'free', value: 100 - cpuData['percent']}
]))
memChart.setOption(createPieChartOption(`${localData['memory']}\n${memData['percent'].toFixed(1)}%`, [
{name: 'process', value: memData['usedProcess']},
{name: 'used', value: memData['used'] - memData['usedProcess']},
{name: 'free', value: memData['free']}
]))
swapChart.setOption(createPieChartOption(`${localData['swap']}\n${swapData['percent'].toFixed(1)}%`, [
{name: 'used', value: swapData['used']},
{name: 'free', value: swapData['free']}
]))
// 磁盘信息
const diskData = hardwareData['disk']
diskData.forEach(
(disk) => {
let diskTitle = `${disk['name']} ${localData['free']} ${convertSize(disk['free'])} ${localData['total']} ${convertSize(disk['total'])}`
// 最后一个把margin-bottom去掉
let diskDiv = createBarChart(diskTitle, disk['percent'])
if (disk === diskData[diskData.length - 1]) {
diskDiv.style.marginBottom = '0'
}
document.getElementById('disk-info').appendChild(createBarChart(diskTitle, disk['percent']))
})
// 随机一言
let motto = mottos[Math.floor(Math.random() * mottos.length)]
let mottoText = motto['text']
let mottoFrom = `${motto['author']} ${motto['source']}`
document.getElementById('motto-text').innerText = mottoText
document.getElementById('motto-from').innerText = mottoFrom
}
main()

View File

@ -0,0 +1,257 @@
{
// 环形图
let cpuInfo = echarts.init(document.getElementById('cpu-chart'));
let memInfo = echarts.init(document.getElementById('mem-chart'));
let swapInfo = echarts.init(document.getElementById('swap-chart'));
let data = JSON.parse(document.getElementById('data').innerText);
let cpuData = data.cpu;
let memData = data.mem;
let swapData = data.swap;
let diskData = data.disk;
let sub_tag_data = {
cpu: data.cpuTags,
mem: data.memTags,
swap: data.swapTags
}
for (let key in sub_tag_data) {
let infoDiv = document.getElementById(key + '-info');
sub_tag_data[key].forEach(tag => {
let tagSpan = document.createElement('div');
tagSpan.innerText = tag;
tagSpan.className = 'chart-label';
infoDiv.appendChild(tagSpan);
});
}
cpuInfo.setOption(getPieOption(data.localization.cpu, cpuData));
memInfo.setOption(getPieOption(data.localization.mem, memData));
swapInfo.setOption(getPieOption(data.localization.swap, swapData));
// 在disks-info中插入每个disk的div用横向柱状图表示用量每一行div显示一个disk不加info-box
diskData.forEach(disk => {
let diskDiv = document.createElement('div');
document.getElementById('disks-info').appendChild(diskDiv);
let diskChart = document.createElement('div');
diskChart.style.width = '100%';
diskChart.style.height = '100px';
diskDiv.appendChild(diskChart);
let diskInfo = echarts.init(diskChart);
// let diskTitle = disk.name + ' {{ FREE }} ' + disk.free + ' {{ TOTAL }} ' + disk.total;
let diskTitle = `${disk.name} ${data.localization.free} ${disk.free} ${data.localization.total} ${disk.total}`;
diskInfo.setOption(getBarOption(diskTitle, disk.percent));
});
let botData = data.bot;
// 清空bot-info
let botInfos = document.getElementsByClassName('bot-info');
while (botInfos.length > 0) {
botInfos[0].remove();
}
botData.forEach(bot => {
// 在hardware-info前面插入一个div
let botDiv = document.createElement('div');
botDiv.className = 'info-box bot-info';
// 在body内的hardware-info前面插入botDiv
document.body.insertBefore(botDiv, document.getElementById('hardware-info'));
let botIconBlock = document.createElement('div');
let botIcon = document.createElement('img');
botIcon.src = bot.icon;
botIcon.className = 'bot-icon';
botIconBlock.appendChild(botIcon);
botDiv.appendChild(botIconBlock);
let botDetail = document.createElement('div');
let botName = document.createElement('div');
botName.className = 'bot-name';
botName.innerText = bot.name;
if (bot.self) {
// 添加颜色
botName.style.color = '#d0e9ff';
}
botDetail.appendChild(botName);
let botTags = document.createElement('div');
botTags.className = 'bot-tag';
botDetail.appendChild(botTags)
bot.tags.forEach((tag, index) => {
if (!tag) {
return;
}
let tagSpan = document.createElement('span');
tagSpan.innerText = tag;
tagSpan.className = 'tag';
if (bot.self) {
// 添加颜色
tagSpan.style.color = '#a2d8f4';
}
botTags.appendChild(tagSpan);
if (index === bot.tags.length - 1) {
tagSpan.setAttribute("suffix", "0")
} else {
tagSpan.setAttribute("suffix", "1")
}
});
botDiv.appendChild(botDetail);
}
)
// 从/js/motto.js中读取mottos{},随机选择一句
let motto = mottos[Math.floor(Math.random() * mottos.length)];
// 正文在中间,作者和来源格式为--作者 来源,在右下方
let mottoDiv = document.getElementById('motto-info');
let mottoText = document.createElement('div');
mottoText.className = 'motto-text';
mottoText.innerText = motto.text;
mottoDiv.appendChild(mottoText);
let mottoAuthor = document.createElement('div');
mottoAuthor.className = 'motto-author';
// motto.author和motto.source可能不存在为空所以要判断
if (!motto.author) {
motto.author = '';
}
if (!motto.source) {
motto.source = '';
}
mottoAuthor.innerText = `\n--${motto.author} ${motto.source}`;
mottoAuthor.style.textAlign = 'right';
mottoDiv.appendChild(mottoAuthor);
function getPieUsage(data){
let total = 0
let used = 0
data.forEach(item => {
total += item.value
if(item.name === 'FREE'){
used += item.value
}
})
return (1 - used / total) * 100
}
function getPieOption(title, data) {
return {
animation: false,
title: {
text: title + '\n' + getPieUsage(data).toFixed(1) + '%',
left: 'center',
top: 'center',
textStyle: {
//文字颜色
lineHeight: 36,
color: '#fff',
fontSize: 30
}
},
tooltip: {
show: true,
trigger: "item",
backgroundColor: "#ffffff00",
// {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
color: ['#a2d8f4', "#ffffff44", '#00a6ff'],
series: [
{
name: 'info',
type: 'pie',
radius: ['80%', '100%'],
center: ['50%', '50%'],
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
}
},
emphasis: {
label: {
show: true,
textStyle: {
fontSize: '50',
fontWeight: 'bold'
}
}
}
},
data: data
}
]
};
}
function getBarOption(title, percent) {
let fillet = 0
if (percent < 5){
fillet = 50
}
// data为百分比最大值为100
return {
background: '#d0e9ff',
title: {
text: title,
left: '5%',
top: 'center',
textStyle: {
color: '#fff',
fontSize: 30
}
},
tooltip: {
show: true,
trigger: "item",
backgroundColor: "#ffffff",
},
grid: {
left: '0',
right: '0',
top: '10%',
bottom: '10%'
},
xAxis: {
type: 'value',
show: false
},
yAxis: {
type: 'category',
data: [''],
show: false
},
series: [
{
name: 'Used',
type: 'bar',
stack: 'total',
data: [percent],
itemStyle: {
normal: {
color: '#a2d8f4',
barBorderRadius: [50, 0, 0, 50]
}
},
},
{
name: 'Free',
type: 'bar',
stack: 'total',
data: [100 - percent],
itemStyle: {
normal: {
color: '#d0e9ff',
barBorderRadius: [fillet, 50, 50, fillet]
}
},
}
]
};
}
}

Some files were not shown because too many files have changed in this diff Show More