feat: 拓扑网管信息页面多语言翻译
This commit is contained in:
@@ -1025,6 +1025,22 @@ export default {
|
|||||||
kbps: "Network entry/exit",
|
kbps: "Network entry/exit",
|
||||||
commandstats: "Command Statistics",
|
commandstats: "Command Statistics",
|
||||||
},
|
},
|
||||||
|
topology: {
|
||||||
|
showAllHide: "Show all hidden items",
|
||||||
|
collapseAll: "Collapse all clusters",
|
||||||
|
expandAll: "Expanded clusters",
|
||||||
|
foldAll: "Folded Cluster",
|
||||||
|
hideEdge: "hidden edge",
|
||||||
|
hideNode: "hidden node",
|
||||||
|
state: "State",
|
||||||
|
normalcy: "Normalcy",
|
||||||
|
exceptions: "Exceptions",
|
||||||
|
refreshTime: "RefreshTime",
|
||||||
|
name: "Name",
|
||||||
|
version: "Version",
|
||||||
|
validityPeriod: "Validity Period",
|
||||||
|
switchLayout: "Switch Layout",
|
||||||
|
},
|
||||||
topologyBuild: {
|
topologyBuild: {
|
||||||
graphMode: "Graph Model",
|
graphMode: "Graph Model",
|
||||||
graphGroup: "Graph Group name",
|
graphGroup: "Graph Group name",
|
||||||
|
|||||||
@@ -1025,6 +1025,22 @@ export default {
|
|||||||
kbps: "网络入口/出口",
|
kbps: "网络入口/出口",
|
||||||
commandstats: "命令统计",
|
commandstats: "命令统计",
|
||||||
},
|
},
|
||||||
|
topology: {
|
||||||
|
showAllHide: "显示所有隐藏项",
|
||||||
|
collapseAll: "折叠所有群组",
|
||||||
|
expandAll: "展开集群",
|
||||||
|
foldAll: "折叠集群",
|
||||||
|
hideEdge: "隐藏边",
|
||||||
|
hideNode: "隐藏节点",
|
||||||
|
state: "状态",
|
||||||
|
normalcy: "正常",
|
||||||
|
exceptions: "异常",
|
||||||
|
refreshTime: "刷新时间",
|
||||||
|
name: "网元名称",
|
||||||
|
version: "网元版本",
|
||||||
|
validityPeriod: "有效期",
|
||||||
|
switchLayout: "切换布局",
|
||||||
|
},
|
||||||
topologyBuild: {
|
topologyBuild: {
|
||||||
graphMode: "图模式",
|
graphMode: "图模式",
|
||||||
graphGroup: "图组名",
|
graphGroup: "图组名",
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ registerNode(
|
|||||||
}
|
}
|
||||||
const style = cfg.style || {};
|
const style = cfg.style || {};
|
||||||
const colorSet = cfg.colorSet || colorSets[0];
|
const colorSet = cfg.colorSet || colorSets[0];
|
||||||
console.log('=== ', cfg);
|
|
||||||
|
|
||||||
// halo for hover
|
// halo for hover
|
||||||
group.addShape('circle', {
|
group.addShape('circle', {
|
||||||
@@ -316,13 +315,13 @@ registerNode(
|
|||||||
// 网元状态标识
|
// 网元状态标识
|
||||||
if (cfg.info) {
|
if (cfg.info) {
|
||||||
const neInfo: any = cfg.info;
|
const neInfo: any = cfg.info;
|
||||||
const hasNeState = neInfo.serverState.neId;
|
const neOnline = neInfo.serverState.online;
|
||||||
const neStateShape = group.addShape('circle', {
|
const neStateShape = group.addShape('circle', {
|
||||||
attrs: {
|
attrs: {
|
||||||
x: r - 3,
|
x: r - 3,
|
||||||
y: -r + 3,
|
y: -r + 3,
|
||||||
r: 5,
|
r: 5,
|
||||||
fill: hasNeState ? '#6DD400' : 'red',
|
fill: neOnline ? '#6DD400' : 'red',
|
||||||
lineWidth: 0.5,
|
lineWidth: 0.5,
|
||||||
stroke: '#FFFFFF',
|
stroke: '#FFFFFF',
|
||||||
},
|
},
|
||||||
@@ -1008,7 +1007,7 @@ const getForceLayoutConfig = (
|
|||||||
onLayoutEnd: () => {
|
onLayoutEnd: () => {
|
||||||
if (largeGraphMode) {
|
if (largeGraphMode) {
|
||||||
graph.getEdges().forEach((edge: any) => {
|
graph.getEdges().forEach((edge: any) => {
|
||||||
console.log('onLayoutEnd', edge.oriLabel);
|
// console.log('onLayoutEnd', edge.oriLabel);
|
||||||
if (!edge.oriLabel) return;
|
if (!edge.oriLabel) return;
|
||||||
edge.update({
|
edge.update({
|
||||||
label: labelFormatter(edge.oriLabel, labelMaxLength),
|
label: labelFormatter(edge.oriLabel, labelMaxLength),
|
||||||
@@ -1341,7 +1340,7 @@ const bindListener = (graph: any) => {
|
|||||||
stopLayout();
|
stopLayout();
|
||||||
if (!shiftKeydown) clearFocusItemState(graph);
|
if (!shiftKeydown) clearFocusItemState(graph);
|
||||||
const { item } = evt;
|
const { item } = evt;
|
||||||
console.log(item);
|
// console.log(item);
|
||||||
// highlight the clicked edge
|
// highlight the clicked edge
|
||||||
graph.setItemState(item, 'focus', true);
|
graph.setItemState(item, 'focus', true);
|
||||||
});
|
});
|
||||||
@@ -1349,16 +1348,20 @@ const bindListener = (graph: any) => {
|
|||||||
// click canvas to cancel all the focus state
|
// click canvas to cancel all the focus state
|
||||||
graph.on('canvas:click', (evt: any) => {
|
graph.on('canvas:click', (evt: any) => {
|
||||||
clearFocusItemState(graph);
|
clearFocusItemState(graph);
|
||||||
console.log(
|
// console.log(
|
||||||
graph.getGroup(),
|
// graph.getGroup(),
|
||||||
graph.getGroup().getBBox(),
|
// graph.getGroup().getBBox(),
|
||||||
graph.getGroup().getCanvasBBox()
|
// graph.getGroup().getCanvasBBox()
|
||||||
);
|
// );
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 导出渲染函数
|
// 导出渲染函数
|
||||||
export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
export function randerGroph(
|
||||||
|
t: any,
|
||||||
|
graphG6Dom: HTMLElement | undefined,
|
||||||
|
data: any
|
||||||
|
) {
|
||||||
if (!graphG6Dom) return;
|
if (!graphG6Dom) return;
|
||||||
|
|
||||||
// graphG6Dom.value.style.backgroundColor = '#2b2f33';
|
// graphG6Dom.value.style.backgroundColor = '#2b2f33';
|
||||||
@@ -1437,10 +1440,10 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div id="show" style="cursor: pointer; margin-bottom: 2px">
|
<div id="show" style="cursor: pointer; margin-bottom: 2px">
|
||||||
1. 显示所有隐藏项
|
1. ${t('views.monitor.topology.showAllHide')}
|
||||||
</div>
|
</div>
|
||||||
<div id="collapseAll" style="cursor: pointer; margin-bottom: 2px">
|
<div id="collapseAll" style="cursor: pointer; margin-bottom: 2px">
|
||||||
2. 折叠所有集群
|
2. ${t('views.monitor.topology.collapseAll')}
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
@@ -1460,10 +1463,10 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div id="expand" style="cursor: pointer; margin-bottom: 2px">
|
<div id="expand" style="cursor: pointer; margin-bottom: 2px">
|
||||||
1. 展开集群
|
1. ${t('views.monitor.topology.expandAll')}
|
||||||
</div>
|
</div>
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
||||||
2. 隐藏节点
|
2. ${t('views.monitor.topology.hideNode')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -1478,10 +1481,10 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div id="collapse" style="cursor: pointer; margin-bottom: 2px">
|
<div id="collapse" style="cursor: pointer; margin-bottom: 2px">
|
||||||
1. 折叠集群
|
1. ${t('views.monitor.topology.foldAll')}
|
||||||
</div>
|
</div>
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
||||||
2. 隐藏节点
|
2. ${t('views.monitor.topology.hideNode')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -1497,7 +1500,7 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
||||||
1. 隐藏边
|
1. ${t('views.monitor.topology.hideEdge')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -1606,11 +1609,6 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
return `<div><span>ID:</span><span>${node.id}</span></div>`;
|
return `<div><span>ID:</span><span>${node.id}</span></div>`;
|
||||||
}
|
}
|
||||||
const serverState = neInfo.serverState;
|
const serverState = neInfo.serverState;
|
||||||
console.log(neInfo);
|
|
||||||
const hasNeID = serverState.neId;
|
|
||||||
if (!hasNeID) {
|
|
||||||
return '<div><span>状态:</span><span>异常</span></div>';
|
|
||||||
}
|
|
||||||
return `
|
return `
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
@@ -1619,19 +1617,27 @@ export function randerGroph(graphG6Dom: HTMLElement | undefined, data: any) {
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div><span>状态:</span><span>
|
<div><strong>${t('views.monitor.topology.state')}:</strong><span>
|
||||||
${hasNeID ? '正常' : '异常'}
|
${
|
||||||
|
neInfo.serverState.online
|
||||||
|
? t('views.monitor.topology.normalcy')
|
||||||
|
: t('views.monitor.topology.exceptions')
|
||||||
|
}
|
||||||
</span></div>
|
</span></div>
|
||||||
<div><span>刷新时间:</span><span>
|
<div><strong>${t('views.monitor.topology.refreshTime')}:</strong><span>
|
||||||
${serverState.refreshTime ?? '--'}
|
${serverState.refreshTime ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
<div><span>ID:</span><span>${hasNeID}</span></div>
|
<div>========================</div>
|
||||||
<div><span>名称:</span><span>${serverState.neName ?? '--'}</span></div>
|
<div><strong>ID:</strong><span>${serverState.neId}</span></div>
|
||||||
<div><span>版本:</span><span>
|
<div><strong>${t('views.monitor.topology.name')}:</strong><span>
|
||||||
|
${serverState.neName ?? '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>IP:</strong><span>${serverState.neIP}</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
||||||
${serverState.version ?? '--'}
|
${serverState.version ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
<div><span>SN:</span><span>${serverState.sn ?? '--'}</span></div>
|
<div><strong>SN:</strong><span>${serverState.sn ?? '--'}</span></div>
|
||||||
<div><span>有效期:</span><span>
|
<div><strong>${t('views.monitor.topology.validityPeriod')}:</strong><span>
|
||||||
${serverState.expire ?? '--'}
|
${serverState.expire ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,14 +25,18 @@ const graphG6Data = reactive<Record<string, any>>({
|
|||||||
/**查询全部网元数据列表 */
|
/**查询全部网元数据列表 */
|
||||||
function fnRanderData() {
|
function fnRanderData() {
|
||||||
if (!graphG6Dom.value) return;
|
if (!graphG6Dom.value) return;
|
||||||
graphG6.value = randerGroph(graphG6Dom.value, graphG6Data);
|
graphG6.value = randerGroph(t, graphG6Dom.value, graphG6Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**网元状态定时器 */
|
||||||
|
const stateTimeout = ref<any>(null);
|
||||||
|
|
||||||
/**查询网元状态 */
|
/**查询网元状态 */
|
||||||
async function fnGetState() {
|
async function fnGetState() {
|
||||||
|
clearTimeout(stateTimeout.value);
|
||||||
for (const node of graphG6Data.nodes) {
|
for (const node of graphG6Data.nodes) {
|
||||||
const ne = node.info;
|
const ne = node.info;
|
||||||
if (ne.neType === 'OMC') continue;
|
// if (ne.neType === 'OMC') continue;
|
||||||
const result = await stateNe(ne.neType, ne.neId);
|
const result = await stateNe(ne.neType, ne.neId);
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
ne.serverState = result.data;
|
ne.serverState = result.data;
|
||||||
@@ -40,16 +44,12 @@ async function fnGetState() {
|
|||||||
ne.serverState.refreshTime,
|
ne.serverState.refreshTime,
|
||||||
'HH:mm:ss'
|
'HH:mm:ss'
|
||||||
);
|
);
|
||||||
|
// 修改网元状态颜色
|
||||||
|
const neShape = graphG6.value.findById(ne.neName);
|
||||||
|
graphG6.value.setItemState(neShape, 'neState', ne.serverState.online);
|
||||||
}
|
}
|
||||||
// 修改网元状态颜色
|
|
||||||
const neShape = graphG6.value.findById(ne.neName);
|
|
||||||
graphG6.value.setItemState(
|
|
||||||
neShape,
|
|
||||||
'neState',
|
|
||||||
result.code === RESULT_CODE_SUCCESS
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
setTimeout(() => fnGetState(), 30_000);
|
stateTimeout.value = setTimeout(() => fnGetState(), 30_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**查询全部网元数据列表 */
|
/**查询全部网元数据列表 */
|
||||||
@@ -73,15 +73,6 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
// 根网管
|
// 根网管
|
||||||
if (item.neType === 'OMC') {
|
if (item.neType === 'OMC') {
|
||||||
rootNode = item.neName;
|
rootNode = item.neName;
|
||||||
item.serverState = {
|
|
||||||
neId: item.neId,
|
|
||||||
neName: item.neName,
|
|
||||||
neType: item.neType,
|
|
||||||
expire: '-',
|
|
||||||
refreshTime: '-',
|
|
||||||
sn: '-',
|
|
||||||
version: '-',
|
|
||||||
};
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
id: item.neName,
|
id: item.neName,
|
||||||
label: item.neName,
|
label: item.neName,
|
||||||
@@ -134,7 +125,6 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
}
|
}
|
||||||
graphG6Data.nodes = nodes;
|
graphG6Data.nodes = nodes;
|
||||||
graphG6Data.edges = edges;
|
graphG6Data.edges = edges;
|
||||||
console.log(graphG6Data);
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
message.warning({
|
message.warning({
|
||||||
@@ -157,7 +147,7 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取网元列表
|
// 获取网元列表G
|
||||||
fnGetList();
|
fnGetList();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -170,151 +160,16 @@ onMounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<!-- 插槽-卡片左侧侧 -->
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
<template #title v-if="false">
|
<template #title> </template>
|
||||||
<div class="button-container" style="margin-bottom: -12px">
|
|
||||||
<a-button type="primary">
|
|
||||||
<template #icon>
|
|
||||||
<PlusOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('common.addText') }}
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<a-button type="primary" danger ghost>
|
|
||||||
<template #icon>
|
|
||||||
<DeleteOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('views.neUser.auth.batchDelText') }}
|
|
||||||
</a-button>
|
|
||||||
<a-popconfirm
|
|
||||||
:title="t('views.neUser.sub.loadDataConfirm')"
|
|
||||||
:ok-text="t('common.ok')"
|
|
||||||
:cancel-text="t('common.cancel')"
|
|
||||||
>
|
|
||||||
<a-button type="dashed" danger>
|
|
||||||
<template #icon>
|
|
||||||
<SyncOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('views.neUser.sub.loadData') }}
|
|
||||||
</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
|
|
||||||
<a-button type="dashed">
|
|
||||||
<template #icon>
|
|
||||||
<ImportOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('views.neUser.sub.import') }}
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<a-popconfirm
|
|
||||||
:title="t('views.neUser.sub.exportConfirm')"
|
|
||||||
ok-text="TXT"
|
|
||||||
ok-type="default"
|
|
||||||
>
|
|
||||||
<a-button type="dashed">
|
|
||||||
<template #icon>
|
|
||||||
<ExportOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('views.neUser.sub.export') }}
|
|
||||||
</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<!-- 插槽-卡片右侧 -->
|
<!-- 插槽-卡片右侧 -->
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-button type="default" @click.prevent="switchLayout()">
|
<a-button type="default" @click.prevent="switchLayout()">
|
||||||
<template #icon><RetweetOutlined /></template>
|
<template #icon><RetweetOutlined /></template>
|
||||||
Switch Layout
|
{{ t('views.monitor.topology.switchLayout') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div ref="graphG6Dom" class="chart"></div>
|
<div ref="graphG6Dom" class="chart"></div>
|
||||||
|
|
||||||
<template v-if="false">
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 200px;
|
|
||||||
background: #e6f7ff;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div><span>状态:</span><span>正常</span></div>
|
|
||||||
<div><span>刷新时间:</span><span>18:37:22</span></div>
|
|
||||||
<div><span>ID:</span><span>neID</span></div>
|
|
||||||
<div><span>名称:</span><span>neName</span></div>
|
|
||||||
<div><span>版本:</span><span>2.2312.8</span></div>
|
|
||||||
<div><span>SN:</span><span>13770707</span></div>
|
|
||||||
<div><span>有效期:</span><span>2024-03-31</span></div>
|
|
||||||
</div>
|
|
||||||
===
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 140px;
|
|
||||||
background: #e6f7ff;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div id="show" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
1. 显示所有隐藏项
|
|
||||||
</div>
|
|
||||||
<div id="collapseAll" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
2. 折叠所有集群
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
===
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100px;
|
|
||||||
background: #e6f7ff;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div id="expand" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
1. 展开集群
|
|
||||||
</div>
|
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
2. 隐藏节点
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
===
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 160px;
|
|
||||||
background: #e6f7ff;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div id="collapse" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
1. 折叠集群
|
|
||||||
</div>
|
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
2. 隐藏节点
|
|
||||||
</div>
|
|
||||||
<div id="restart" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
3. 重启
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
===
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100px;
|
|
||||||
background: #e6f7ff;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div id="hide" style="cursor: pointer; margin-bottom: 2px">
|
|
||||||
1. 隐藏边
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 组件 -->
|
|
||||||
<div class="charts">
|
|
||||||
<ChartGraphG6></ChartGraphG6>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-card>
|
</a-card>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</template>
|
</template>
|
||||||
@@ -325,10 +180,4 @@ onMounted(() => {
|
|||||||
height: calc(100vh - 300px);
|
height: calc(100vh - 300px);
|
||||||
background-color: rgb(43, 47, 51);
|
background-color: rgb(43, 47, 51);
|
||||||
}
|
}
|
||||||
.charts {
|
|
||||||
width: 100%;
|
|
||||||
height: 500px;
|
|
||||||
background-color: rgb(238, 237, 237);
|
|
||||||
margin-top: 32px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user