Commit ec5a85e5 authored by qmhu's avatar qmhu
Browse files

refine dashboard for menus and overview

Signed-off-by: default avatarqmhu <brillantroad@gmail.com>
Showing with 519 additions and 118 deletions
+519 -118
......@@ -6,7 +6,7 @@
<title>Crane Dashboard</title>
<meta name="description" content="React UI Component" />
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/crane.svg" sizes="360x360" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
<meta name="msapplication-TileColor" content="#FFFFFF" />
<link rel="mask-icon" href="/favicon.svg" color="#FFFFFF" />
......
......@@ -19,6 +19,7 @@
"i18next": "^21.6.6",
"i18next-browser-languagedetector": "^6.1.3",
"i18next-icu": "^2.0.3",
"intl-messageformat": "^9.11.1",
"lodash": "^4.17.21",
"mockjs": "^1.1.0",
"qrcode.react": "^3.0.2",
......@@ -1995,7 +1996,6 @@
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
"integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"peer": true,
"dependencies": {
"@formatjs/intl-localematcher": "0.2.25",
"tslib": "^2.1.0"
......@@ -2005,7 +2005,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz",
"integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==",
"peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
......@@ -2014,7 +2013,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz",
"integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==",
"peer": true,
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/icu-skeleton-parser": "1.3.6",
......@@ -2025,7 +2023,6 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz",
"integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==",
"peer": true,
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"tslib": "^2.1.0"
......@@ -2035,7 +2032,6 @@
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
"integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
......@@ -5998,7 +5994,6 @@
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz",
"integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==",
"peer": true,
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/fast-memoize": "1.2.1",
......@@ -10181,7 +10176,6 @@
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
"integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"peer": true,
"requires": {
"@formatjs/intl-localematcher": "0.2.25",
"tslib": "^2.1.0"
......@@ -10191,7 +10185,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz",
"integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==",
"peer": true,
"requires": {
"tslib": "^2.1.0"
}
......@@ -10200,7 +10193,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz",
"integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==",
"peer": true,
"requires": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/icu-skeleton-parser": "1.3.6",
......@@ -10211,7 +10203,6 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz",
"integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==",
"peer": true,
"requires": {
"@formatjs/ecma402-abstract": "1.11.4",
"tslib": "^2.1.0"
......@@ -10221,7 +10212,6 @@
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
"integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"peer": true,
"requires": {
"tslib": "^2.1.0"
}
......@@ -13108,7 +13098,6 @@
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz",
"integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==",
"peer": true,
"requires": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/fast-memoize": "1.2.1",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="306px" height="186px" viewBox="144.139 425.446 306 186" enable-background="new 144.139 425.446 306 186"
xml:space="preserve">
<path fill="#58BDA6" d="M267.919,572.702c-0.372,5.728-4.972,10.091-10.27,9.743l-40.779-2.65c-5.3-0.347-9.293-5.269-8.923-10.991
l2.974-45.702c0.373-5.728,4.973-10.088,10.271-9.743l40.78,2.652c5.299,0.345,9.293,5.267,8.921,10.99L267.919,572.702z"/>
<path fill="#EE7300" d="M355.802,528.969c-28.058-24.713-63.021-62.657-91.196-87.232c-1.938-1.69-5.604-3.409-7.457-2.647
c-1.938,0.795-3.404,4.46-3.778,7.058c-1.761,12.192-2.91,28.237-4.656,40.433c-0.437,3.041-1.971,6.067-3.571,8.762
c-2.041,3.435-0.873,12.792,2.958,15.723c3.085,2.357,4.303,5.096,1.854,7.834c-1.351,1.512-4.525,1.391-6.992,2.032
c2.374,2.482,5.765,2.633,9.24-0.084c3.808-2.979,2.631-7.084-4.054-14.46c4.628-3.659,5.886-7.839,2.424-13.33
c-1.104-1.75-0.191-4.886,0.068-7.356c1.027-9.761,2.094-23.278,3.315-33.019c0.292-2.324,1.237-4.564,2.349-8.479
c26.078,34.224,56.794,78.868,82.623,112.767c0.93-6.764-0.387-17.9-0.708-23.131c-0.193-3.154-5.785-8.536-7.861-11.352
c-3.039-4.109-6.746-7.742-9.644-11.94c-0.76-1.101-0.824-2.206,0.128-3.594c1.252-1.816,2.925,0.178,3.865,1.018
c9.287,8.277,25.465,24.596,31.02,35.665c0.248,0.495-1.506-11.808-0.865-10.746"/>
<path d="M185.44,554.611v-4.04c0-2.692-0.57-4.727-1.712-6.104c-1.145-1.375-2.634-2.062-4.475-2.062
c-3.021-0.056-5.026,0.505-6.021,1.686c-0.994,1.179-1.49,2.806-1.49,4.881l-0.11,31.229c0,1.796,0.515,3.188,1.548,4.166
c1.028,0.982,2.834,1.476,5.412,1.476c1.618,0,2.908-0.295,3.866-0.883c0.957-0.593,1.692-1.334,2.21-2.231
c0.515-0.896,0.828-1.88,0.938-2.946c0.11-1.064,0.166-2.076,0.166-3.028v-5.726h19.442v7.744c0,2.693-0.534,5.176-1.603,7.449
c-1.067,2.271-2.727,4.224-4.972,5.85c-2.247,1.629-5.156,2.894-8.729,3.788c-3.573,0.897-7.826,1.347-12.761,1.347
c-4.493,0-8.305-0.447-11.435-1.347c-3.132-0.896-5.688-2.201-7.679-3.914c-1.988-1.71-3.442-3.813-4.363-6.312
c-0.922-2.497-1.382-5.349-1.382-8.545v-25.929c0-6.899,2.117-11.979,6.354-15.233c4.232-3.254,10.808-4.883,19.72-4.883
c4.124,0,7.823,0.353,11.104,1.054c3.275,0.702,6.058,1.782,8.341,3.239c2.282,1.461,4.033,3.354,5.248,5.684
s1.821,5.092,1.821,8.29v5.304H185.44V554.611z"/>
<path fill="#FFFFFF" d="M231.8,574.649l-16.795-1.156l3.754-54.526l24.521,1.688c6.934,0.479,12.024,1.985,15.27,4.521
c3.243,2.536,4.682,6.521,4.308,11.945c-0.2,2.909-0.979,5.362-2.329,7.364c-1.354,2.001-3.818,3.488-7.4,4.457l-0.009,0.146
c2.324,0.553,4.212,1.483,5.653,2.801c1.443,1.316,2.162,2.924,2.161,4.824c0.049,1.125,0.066,2.486,0.052,4.094
c-0.013,1.604-0.028,3.235-0.047,4.892c-0.019,1.655-0.018,3.236,0.007,4.749c0.023,1.514,0.135,2.712,0.329,3.603
c0.389,0.854,0.887,1.521,1.49,2.002l-0.051,0.729l-18.317-1.261c-0.219-0.552-0.392-1.086-0.515-1.608
c-0.125-0.518-0.199-1.046-0.228-1.586c0.039-2.43,0.165-4.724,0.379-6.877c0.211-2.148,0.247-4.084,0.11-5.799
c-0.139-1.712-0.569-3.105-1.294-4.18c-0.726-1.074-2.071-1.726-4.036-1.958l-5.533-0.381L231.8,574.649z M233.957,543.314
l5.726,0.396c1.208,0.081,2.222-0.041,3.045-0.375c0.821-0.334,1.479-0.801,1.966-1.399s0.842-1.305,1.058-2.118
c0.216-0.812,0.354-1.631,0.409-2.455c0.108-1.6-0.026-2.875-0.409-3.827c-0.38-0.949-1.034-1.679-1.958-2.18
c-0.923-0.501-2.132-0.842-3.62-1.017c-1.49-0.177-3.255-0.311-5.294-0.401L233.957,543.314z"/>
<path d="M265.164,595.689l18.116-63.132h23.423l18.006,63.132h-19.663l-2.762-12.291h-15.246l-2.318,12.291H265.164z
M294.992,544.005h-0.222l-5.634,28.282h11.269L294.992,544.005z"/>
<path d="M352.709,556.745l-0.223,0.168l1.77,35.188h-18.448v-63.132h19.995l15.024,35.269h0.331l-1.88-35.269h18.45V592.1h-19.887
L352.709,556.745z"/>
<path d="M397.406,595.689v-63.132h44.521v12.625H416.85V556.8h24.305v12.627H416.85v13.636h26.403v12.627L397.406,595.689
L397.406,595.689z"/>
<circle fill="#FFFFFF" cx="344.901" cy="536.967" r="3.136"/>
</svg>
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Routes, useNavigate } from 'react-router-dom';
import { Menu } from 'tdesign-react';
import { useSideMenuSelection } from '../../hooks/useSideMenuSelection';
import { RoutesEnum } from '../../routes/routeEnum';
export const SideMenu: React.FC = () => {
const { t } = useTranslation();
const selection = useSideMenuSelection();
const navigate = useNavigate();
return (
<Menu style={{ minHeight: '100%' }} theme="dark" value={selection}>
<Menu.MenuItem
value={RoutesEnum.OVERVIEW}
onClick={() => {
navigate(RoutesEnum.OVERVIEW);
}}
>
{t('成本概览')}
</Menu.MenuItem>
<Menu.MenuItem
value={RoutesEnum.INSIGHT}
onClick={() => {
navigate(RoutesEnum.INSIGHT);
}}
>
{t('成本洞察')}
</Menu.MenuItem>
</Menu>
);
};
......@@ -4,4 +4,3 @@ export * from './useGrafanaQueyStr';
export * from './useIsIntersecting';
export * from './useIsNeedSelectNamespace';
export * from './useIsValidPanel';
export * from './useSideMenuSelection';
import { matchPath, matchRoutes, useLocation, useRoutes } from 'react-router-dom';
import { RoutesEnum } from 'router/routeEnum';
export const useSideMenuSelection = () => {
const { pathname } = useLocation();
const isOverview = matchPath(`${RoutesEnum.OVERVIEW}/*`, pathname);
const isInsight = matchPath(`${RoutesEnum.INSIGHT}/*`, pathname);
if (isOverview) return RoutesEnum.OVERVIEW;
if (isInsight) return RoutesEnum.INSIGHT;
return null;
};
import type { EChartOption } from 'echarts';
import { getChartDataSet, ONE_WEEK_LIST } from 'utils/chart';
export const getLineChartOptions = (dateTime: Array<string> = []): EChartOption => {
const [timeArray, inArray, outArray] = getChartDataSet(dateTime);
return {
tooltip: {
trigger: 'item',
},
grid: {
left: '0',
right: '20px',
top: '5px',
bottom: '36px',
containLabel: true,
},
legend: {
left: 'center',
bottom: '0',
orient: 'horizontal', // legend 横向布局。
data: ['本月', '上月'],
textStyle: {
fontSize: 12,
},
},
xAxis: {
type: 'category',
data: timeArray,
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#E3E6EB',
width: 1,
},
},
},
yAxis: {
type: 'value',
},
series: [
{
name: '本月',
data: outArray,
type: 'line',
smooth: false,
showSymbol: true,
symbol: 'circle',
symbolSize: 8,
itemStyle: {
borderWidth: 1,
},
areaStyle: {
color: '#0053D92F',
},
},
{
name: '上月',
data: inArray,
type: 'line',
smooth: false,
showSymbol: true,
symbol: 'circle',
symbolSize: 8,
itemStyle: {
borderWidth: 1,
},
},
],
};
};
export const getPieChartOptions = (radius = 42): EChartOption => ({
tooltip: {
trigger: 'item',
},
grid: {
top: '0',
right: '0',
},
legend: {
itemWidth: 12,
itemHeight: 4,
textStyle: {
fontSize: 12,
},
left: 'center',
bottom: '0',
orient: 'horizontal', // legend 横向布局。
},
series: [
{
name: '命名空间成本分布',
type: 'pie',
radius: ['48%', '60%'],
avoidLabelOverlap: false,
silent: true,
itemStyle: {
borderWidth: 1,
},
label: {
show: true,
position: 'center',
formatter: ['{value|{d}%}', '{name|{b}占比}'].join('\n'),
rich: {
value: {
fontSize: 28,
fontWeight: 'normal',
lineHeight: 46,
},
name: {
color: '#909399',
fontSize: 12,
lineHeight: 14,
},
},
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: 'kube-system' },
{ value: radius * 7, name: 'crane-system' },
],
},
],
});
export const getBarChartOptions = (dateTime: Array<string> = []): EChartOption => {
const [timeArray, inArray, outArray] = getChartDataSet(dateTime);
return {
tooltip: {
trigger: 'item',
},
xAxis: {
type: 'category',
data: timeArray,
axisLine: {
lineStyle: {
width: 1,
},
},
},
yAxis: {
type: 'value',
},
grid: {
top: '5%',
left: '25px',
right: 0,
bottom: '60px',
},
legend: {
icon: 'rect',
itemWidth: 12,
itemHeight: 4,
itemGap: 48,
textStyle: {
fontSize: 12,
color: 'rgba(0, 0, 0, 0.6)',
},
left: 'center',
bottom: '0',
orient: 'horizontal',
data: ['本月', '上月'],
},
series: [
{
name: '本月',
data: outArray,
type: 'bar',
},
{
name: '上月',
data: inArray,
type: 'bar',
},
],
};
};
// PieChartIcon Data
export const MICRO_CHART_OPTIONS_LINE: EChartOption = {
xAxis: {
type: 'category',
show: false,
data: ONE_WEEK_LIST,
},
yAxis: {
show: false,
type: 'value',
},
grid: {
top: 0,
left: 0,
right: 0,
bottom: 0,
tooltip: {
show: false,
},
},
color: ['#fff'],
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line',
showSymbol: false,
},
],
};
// BarChartIcon Data
export const MICRO_CHART_OPTIONS_BAR: EChartOption = {
xAxis: {
type: 'category',
show: false,
data: ONE_WEEK_LIST,
},
yAxis: {
show: false,
type: 'value',
},
grid: {
top: 0,
left: 0,
right: 0,
bottom: 0,
tooltip: {
show: false,
},
},
series: [
{
data: [
100,
130,
184,
218,
{
value: 135,
itemStyle: {
opacity: 0.2,
},
},
{
value: 118,
itemStyle: {
opacity: 0.2,
},
},
{
value: 60,
itemStyle: {
opacity: 0.2,
},
},
],
type: 'bar',
barWidth: 9,
},
],
};
.cpuChartPanel {
margin-top: 16px;
}
import React, { useState } from 'react';
import { Col, Row, Card } from 'tdesign-react';
import ReactEcharts from 'echarts-for-react';
import useDynamicChart from 'hooks/useDynamicChart';
import LastWeekDatePicker from 'components/DatePicker';
import { getLineChartOptions } from '../chart';
import Style from './CpuChart.module.less';
const lineOptions = getLineChartOptions();
const CpuChart = () => {
const [customOptions, setCustomOptions] = useState(lineOptions);
const onTimeChange = (value: Array<string>) => {
const options = getLineChartOptions(value);
setCustomOptions(options);
};
const dynamicLineChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
borderColor: ['series.0.itemStyle.borderColor', 'series.1.itemStyle.borderColor'],
});
return (
<Row gutter={[16, 16]} className={Style.cpuChartPanel}>
<Col span={12}>
<Card title='CPU 资源使用' actions={LastWeekDatePicker(onTimeChange)}>
<ReactEcharts option={dynamicLineChartOption} notMerge={true} lazyUpdate={false} />
</Card>
</Col>
</Row>
);
};
export default React.memo(CpuChart);
.memoryChartPanel {
margin-top: 16px;
}
import React, { useState } from 'react';
import { Col, Row, Card } from 'tdesign-react';
import ReactEcharts from 'echarts-for-react';
import useDynamicChart from 'hooks/useDynamicChart';
import LastWeekDatePicker from 'components/DatePicker';
import { getLineChartOptions } from '../chart';
import Style from './MemoryChart.module.less';
const lineOptions = getLineChartOptions();
const MemoryChart = () => {
const [customOptions, setCustomOptions] = useState(lineOptions);
const onTimeChange = (value: Array<string>) => {
const options = getLineChartOptions(value);
setCustomOptions(options);
};
const dynamicLineChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
borderColor: ['series.0.itemStyle.borderColor', 'series.1.itemStyle.borderColor'],
});
return (
<Row gutter={[16, 16]} className={Style.cpuChartPanel}>
<Col span={12}>
<Card title='Memory 资源使用' actions={LastWeekDatePicker(onTimeChange)}>
<ReactEcharts option={dynamicLineChartOption} notMerge={true} lazyUpdate={false} />
</Card>
</Col>
</Row>
);
};
export default React.memo(MemoryChart);
.middleChartPanel {
margin-top: 16px;
}
import React, { useState } from 'react';
import { Col, Row, Card } from 'tdesign-react';
import ReactEcharts from 'echarts-for-react';
import useDynamicChart from 'hooks/useDynamicChart';
import LastWeekDatePicker from 'components/DatePicker';
import { getLineChartOptions, getPieChartOptions } from '../chart';
import Style from './MiddleChart.module.less';
const lineOptions = getLineChartOptions();
const pieOptions = getPieChartOptions();
const MiddleChart = () => {
const [customOptions, setCustomOptions] = useState(lineOptions);
const onTimeChange = (value: Array<string>) => {
const options = getLineChartOptions(value);
setCustomOptions(options);
};
const dynamicLineChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
borderColor: ['series.0.itemStyle.borderColor', 'series.1.itemStyle.borderColor'],
});
const dynamicPieChartOption = useDynamicChart(pieOptions, {
placeholderColor: ['legend.textStyle.color'],
containerColor: ['series.0.itemStyle.borderColor'],
textColor: ['label.color', 'label.color'],
});
return (
<Row gutter={[16, 16]} className={Style.middleChartPanel}>
<Col xs={12} xl={9}>
<Card title='成本走势' subtitle='(元)' actions={LastWeekDatePicker(onTimeChange)}>
<ReactEcharts option={dynamicLineChartOption} notMerge={true} lazyUpdate={false} />
</Card>
</Col>
<Col xs={12} xl={3}>
<Card title='命名空间成本分布' subtitle='2021-12'>
<ReactEcharts option={dynamicPieChartOption} notMerge={true} lazyUpdate={true} />
</Card>
</Col>
</Row>
);
};
export default React.memo(MiddleChart);
......@@ -4,7 +4,7 @@ import Board, { ETrend, IBoardProps, TimeType } from 'components/BoardChart';
const PANE_LIST: Array<IBoardProps> = [
{
title: 'Nodes Monthly Estimated Costs',
title: '当月总成本',
countPrefix: '¥ ',
trend: ETrend.up,
trendNum: '20.5%',
......@@ -20,7 +20,7 @@ by (node)) * 730 * (100/100.0)`,
timeType: TimeType.Range,
},
{
title: 'Total Requests Monthly Estimated Costs',
title: '预测每月总成本',
countPrefix: '¥ ',
trend: ETrend.up,
trendNum: '20.5%',
......@@ -49,32 +49,7 @@ sum(
timeType: TimeType.Range,
},
{
title: 'Total Usage Monthly Estimated Costs',
countPrefix: '¥ ',
trend: ETrend.up,
trendNum: '20.5%',
// Icon: <PieChartIcon />,
query: `sum (
sum(label_replace(irate(container_cpu_usage_seconds_total{container!="POD", container!="",image!=""}[1h]), "node", "$1", "instance", "(.*)")) by (container, pod, node, namespace)
* on (node) group_left()
avg(
avg_over_time(node_cpu_hourly_cost[1h]) * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet",label_node_kubernetes_io_instance_type!~"eklet"}
) by (node)
) by (node)
+
sum(label_replace(avg_over_time(container_memory_working_set_bytes{container!="POD",container!="",image!=""}[1h]), "node", "$1", "instance", "(.*)")) by (container, pod, node, namespace) / 1024.0 / 1024.0 / 1024.0
* on (node) group_left()
avg(
avg_over_time(node_ram_hourly_cost[1h]) * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"}
) by (node)
) by (node)
) * 730 * (100./100.)`,
timeType: TimeType.Range,
},
{
title: 'Cpu Requests Monthly Estimated Costs',
title: '当月CPU总成本',
query: `sum(
sum(kube_pod_container_resource_requests{resource="cpu", unit="core"}) by (container, pod, node, namespace)
* on (node) group_left()
......@@ -89,41 +64,13 @@ sum(
timeType: TimeType.Range,
},
{
title: 'Cpu Usage Monthly Estimated Costs',
query: `sum(
sum(label_replace(irate(container_cpu_usage_seconds_total{container!="POD", container!="",image!=""}[1h]), "node", "$1", "instance", "(.*)")) by (container, pod, node, namespace) * on (node) group_left()
avg(
avg_over_time(node_cpu_hourly_cost[1h]) * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"}
) by (node)
) by (node)
) * 730 * (100./100.)`,
countPrefix: '¥ ',
trend: ETrend.down,
trendNum: '20.5%',
timeType: TimeType.Range,
},
{
title: 'Ram Requests Monthly Estimated Costs',
title: '当月Memory总成本',
query: `sum(
sum(kube_pod_container_resource_requests{resource="memory", unit="byte", namespace!=""} / 1024./ 1024. / 1024.) by (container, pod, node, namespace) * on (node) group_left()
avg(
avg_over_time(node_ram_hourly_cost[1h]) * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"}
) by (node)
) by (node)
) * 730 * (100./100.)`,
countPrefix: '¥ ',
trend: ETrend.down,
trendNum: '20.5%',
timeType: TimeType.Range,
},
{
title: 'Ram Usage Monthly Estimated Costs',
query: `sum(
sum(label_replace(avg_over_time(container_memory_working_set_bytes{container!="POD",container!="",image!=""}[1h]), "node", "$1", "instance", "(.*)")) by (container, pod, node, namespace) / 1024.0 / 1024.0 / 1024.0 * on (node) group_left()
avg(
avg_over_time(node_ram_hourly_cost[1h]) * on (node) group_left() max(kube_node_labels{label_beta_kubernetes_io_instance_type!~"eklet", label_node_kubernetes_io_instance_type!~"eklet"}
) by (node)
) by (node)
) * 730 * (100./100.)`,
countPrefix: '¥ ',
trend: ETrend.down,
......
export const SALE_TREND_LIST = [
{
growUp: 1,
productName: '国家电网有限公司',
count: 7059,
date: '2021-09-01',
},
{
growUp: -1,
productName: '深圳燃气集团股份有限公司',
count: 6437,
date: '2021-09-01',
},
{
growUp: 4,
productName: '国家烟草专卖局',
count: 4221,
date: '2021-09-01',
},
{
growUp: 3,
productName: '中国电信集团有限公司',
count: 3317,
date: '2021-09-01',
},
{
growUp: -3,
productName: '中国移动通信集团有限公司',
count: 3015,
date: '2021-09-01',
},
{
growUp: -3,
productName: '新余市办公用户采购项目',
count: 2015,
date: '2021-09-12',
},
];
export const PURCHASE_TREND_LIST = [
{
growUp: 1,
productName: '腾讯科技(深圳)有限公司',
count: 3015,
date: '2021-09-01',
},
{
growUp: -1,
productName: '大润发有限公司',
count: 2015,
date: '2021-09-01',
},
{
growUp: 6,
productName: '四川海底捞股份有限公司',
count: 1815,
date: '2021-09-11',
},
{
growUp: -3,
productName: '索尼(中国)有限公司',
count: 1015,
date: '2021-09-21',
},
{
growUp: -4,
productName: '松下电器(中国)有限公司',
count: 445,
date: '2021-09-19',
},
{
growUp: -3,
productName: '新余市办公用户采购项目',
count: 2015,
date: '2021-09-12',
},
];
import React, { memo } from 'react';
import TopPanel from './components/TopPanel';
import MiddleChart from "./components/MiddleChart";
import CpuChart from "./components/CpuChart";
import MemoryChart from "./components/MemoryChart";
const DashBoard = () => (
<div style={{ overflowX: 'hidden' }}>
<TopPanel />
<MiddleChart />
<CpuChart />
<MemoryChart />
</div>
);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment