feat(lite/component): Linear Chart (#6376)
This commit is contained in:
parent
41f5634b7a
commit
aebb47ad38
@ -21,6 +21,8 @@
|
|||||||
"complex-matcher": "^0.7.0",
|
"complex-matcher": "^0.7.0",
|
||||||
"d3-time-format": "^4.1.0",
|
"d3-time-format": "^4.1.0",
|
||||||
"decorator-synchronized": "^0.6.0",
|
"decorator-synchronized": "^0.6.0",
|
||||||
|
"echarts": "^5.3.3",
|
||||||
|
"human-format": "^1.0.0",
|
||||||
"json-rpc-2.0": "^1.3.0",
|
"json-rpc-2.0": "^1.3.0",
|
||||||
"json5": "^2.2.1",
|
"json5": "^2.2.1",
|
||||||
"limit-concurrency-decorator": "^0.5.0",
|
"limit-concurrency-decorator": "^0.5.0",
|
||||||
@ -28,6 +30,7 @@
|
|||||||
"make-error": "^1.3.6",
|
"make-error": "^1.3.6",
|
||||||
"pinia": "^2.0.14",
|
"pinia": "^2.0.14",
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
|
"vue-echarts": "^6.2.3",
|
||||||
"vue-i18n": "9",
|
"vue-i18n": "9",
|
||||||
"vue-router": "^4.0.16"
|
"vue-router": "^4.0.16"
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@ import favicon from "@/assets/favicon.svg";
|
|||||||
import AppHeader from "@/components/AppHeader.vue";
|
import AppHeader from "@/components/AppHeader.vue";
|
||||||
import AppLogin from "@/components/AppLogin.vue";
|
import AppLogin from "@/components/AppLogin.vue";
|
||||||
import InfraPoolList from "@/components/infra/InfraPoolList.vue";
|
import InfraPoolList from "@/components/infra/InfraPoolList.vue";
|
||||||
|
import { useChartTheme } from "@/composables/chart-theme.composable";
|
||||||
import { useXenApiStore } from "@/stores/xen-api.store";
|
import { useXenApiStore } from "@/stores/xen-api.store";
|
||||||
|
|
||||||
let link: HTMLLinkElement | null = document.querySelector("link[rel~='icon']");
|
let link: HTMLLinkElement | null = document.querySelector("link[rel~='icon']");
|
||||||
@ -44,6 +45,8 @@ watchEffect(() => {
|
|||||||
xenApiStore.init();
|
xenApiStore.init();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useChartTheme();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
@ -55,14 +58,14 @@ watchEffect(() => {
|
|||||||
max-width: 37rem;
|
max-width: 37rem;
|
||||||
height: calc(100vh - 9rem);
|
height: calc(100vh - 9rem);
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
background-color: var(--background-color-primary);
|
|
||||||
border-right: 1px solid var(--color-blue-scale-400);
|
border-right: 1px solid var(--color-blue-scale-400);
|
||||||
|
background-color: var(--background-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
flex: 1;
|
|
||||||
background-color: var(--background-color-secondary);
|
|
||||||
height: calc(100vh - 9rem);
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
flex: 1;
|
||||||
|
height: calc(100vh - 9rem);
|
||||||
|
background-color: var(--background-color-secondary);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
59
@xen-orchestra/lite/src/components/charts/ChartSummary.vue
Normal file
59
@xen-orchestra/lite/src/components/charts/ChartSummary.vue
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chart-summary">
|
||||||
|
<div>
|
||||||
|
<div class="label">{{ $t("total-used") }}</div>
|
||||||
|
<div>
|
||||||
|
{{ usedPercent }}%
|
||||||
|
<br />
|
||||||
|
{{ valueFormatter(used) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="label">{{ $t("total-free") }}</div>
|
||||||
|
<div>
|
||||||
|
{{ freePercent }}%
|
||||||
|
<br />
|
||||||
|
{{ valueFormatter(total - used) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, inject } from "vue";
|
||||||
|
import { percent } from "@/libs/utils";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
total: number;
|
||||||
|
used: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const usedPercent = computed(() => percent(props.used, props.total));
|
||||||
|
|
||||||
|
const freePercent = computed(() =>
|
||||||
|
percent(props.total - props.used, props.total)
|
||||||
|
);
|
||||||
|
|
||||||
|
const valueFormatter = inject("valueFormatter") as (value: number) => string;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="postcss" scoped>
|
||||||
|
.chart-summary {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
display: flex;
|
||||||
|
margin-top: 2rem;
|
||||||
|
color: var(--color-blue-scale-200);
|
||||||
|
gap: 4rem;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
</style>
|
38
@xen-orchestra/lite/src/components/charts/LinearChart.md
Normal file
38
@xen-orchestra/lite/src/components/charts/LinearChart.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# LinearChart component
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<LinearChart
|
||||||
|
title="Chart title"
|
||||||
|
subtitle="Chart subtitle"
|
||||||
|
:data="data"
|
||||||
|
:value-formatter="customValueFormatter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { LinearChartData } from "@/types/chart";
|
||||||
|
import LinearChart from "@/components/charts/LinearChart.vue";
|
||||||
|
|
||||||
|
const data: LinearChartData = [
|
||||||
|
{
|
||||||
|
label: "First series",
|
||||||
|
data: [
|
||||||
|
{ date: "...", value: 1234 },
|
||||||
|
{ date: "...", value: 1234 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Second series",
|
||||||
|
data: [
|
||||||
|
{ date: "...", value: 1234 },
|
||||||
|
{ date: "...", value: 1234 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const customValueFormatter = (value: number) => {
|
||||||
|
return `${value} (Doubled: ${value * 2})`;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
89
@xen-orchestra/lite/src/components/charts/LinearChart.vue
Normal file
89
@xen-orchestra/lite/src/components/charts/LinearChart.vue
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<UiCard class="linear-chart">
|
||||||
|
<VueCharts :option="option" autoresize class="chart" />
|
||||||
|
<slot name="summary" />
|
||||||
|
</UiCard>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { EChartsOption } from "echarts";
|
||||||
|
import { computed, provide } from "vue";
|
||||||
|
import VueCharts from "vue-echarts";
|
||||||
|
import type { LinearChartData } from "@/types/chart";
|
||||||
|
import { LineChart } from "echarts/charts";
|
||||||
|
import {
|
||||||
|
GridComponent,
|
||||||
|
LegendComponent,
|
||||||
|
TitleComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
} from "echarts/components";
|
||||||
|
import { use } from "echarts/core";
|
||||||
|
import { CanvasRenderer } from "echarts/renderers";
|
||||||
|
import type { OptionDataValue } from "echarts/types/src/util/types";
|
||||||
|
import UiCard from "@/components/ui/UiCard.vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
title?: string;
|
||||||
|
subtitle?: string;
|
||||||
|
data: LinearChartData;
|
||||||
|
valueFormatter?: (value: number) => string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const valueFormatter = (value: OptionDataValue | OptionDataValue[]) => {
|
||||||
|
if (props.valueFormatter) {
|
||||||
|
return props.valueFormatter(value as number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
provide("valueFormatter", valueFormatter);
|
||||||
|
|
||||||
|
use([
|
||||||
|
CanvasRenderer,
|
||||||
|
LineChart,
|
||||||
|
GridComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
TitleComponent,
|
||||||
|
LegendComponent,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const option = computed<EChartsOption>(() => ({
|
||||||
|
title: {
|
||||||
|
text: props.title,
|
||||||
|
subtext: props.subtitle,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: props.data.map((series) => series.label),
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
valueFormatter,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "time",
|
||||||
|
axisLabel: {
|
||||||
|
showMinLabel: true,
|
||||||
|
showMaxLabel: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
axisLabel: {
|
||||||
|
formatter: valueFormatter,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: props.data.map((series, index) => ({
|
||||||
|
type: "line",
|
||||||
|
name: series.label,
|
||||||
|
zlevel: index + 1,
|
||||||
|
data: series.data.map((item) => [item.date, item.value]),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="postcss" scoped>
|
||||||
|
.chart {
|
||||||
|
width: 50rem;
|
||||||
|
height: 30rem;
|
||||||
|
}
|
||||||
|
</style>
|
382
@xen-orchestra/lite/src/composables/chart-theme.composable.ts
Normal file
382
@xen-orchestra/lite/src/composables/chart-theme.composable.ts
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
import { provide } from "vue";
|
||||||
|
import { THEME_KEY } from "vue-echarts";
|
||||||
|
|
||||||
|
export const useChartTheme = () => {
|
||||||
|
provide(THEME_KEY, {
|
||||||
|
color: ["#8F84FF", "#EF7F18"],
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
textStyle: {},
|
||||||
|
grid: {
|
||||||
|
top: 80,
|
||||||
|
left: 80,
|
||||||
|
right: 20,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
textStyle: {
|
||||||
|
color: "#1A1B38",
|
||||||
|
fontFamily: "Poppins, sans-serif",
|
||||||
|
fontWeight: 500,
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
subtextStyle: {
|
||||||
|
color: "#9899A5",
|
||||||
|
fontFamily: "Poppins, sans-serif",
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
showSymbol: false,
|
||||||
|
symbolSize: 10,
|
||||||
|
symbol: "circle",
|
||||||
|
smooth: false,
|
||||||
|
},
|
||||||
|
radar: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
symbolSize: 10,
|
||||||
|
symbol: "circle",
|
||||||
|
smooth: false,
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
itemStyle: {
|
||||||
|
barBorderWidth: 0,
|
||||||
|
barBorderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pie: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scatter: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
boxplot: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
parallel: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sankey: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
funnel: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gauge: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
candlestick: {
|
||||||
|
itemStyle: {
|
||||||
|
color: "#eb8146",
|
||||||
|
color0: "transparent",
|
||||||
|
borderColor: "#d95850",
|
||||||
|
borderColor0: "#58c470",
|
||||||
|
borderWidth: "2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
graph: {
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#cccccc",
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
width: 1,
|
||||||
|
color: "#aaaaaa",
|
||||||
|
},
|
||||||
|
symbolSize: "10",
|
||||||
|
symbol: "emptyArrow",
|
||||||
|
smooth: true,
|
||||||
|
color: ["#893448", "#d95850", "#eb8146", "#ffb248", "#f2d643", "#ebdba4"],
|
||||||
|
label: {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: "#f3f3f3",
|
||||||
|
borderColor: "#999999",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: "#ffb248",
|
||||||
|
borderColor: "#eb8146",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
geo: {
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: "#f3f3f3",
|
||||||
|
borderColor: "#999999",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: "#ffb248",
|
||||||
|
borderColor: "#eb8146",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
categoryAxis: {
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: "#aaaaaa",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
color: "#999999",
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: ["#e6e6e6"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false,
|
||||||
|
areaStyle: {
|
||||||
|
color: ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valueAxis: {
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: "#aaaaaa",
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: "#333",
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
color: "#9899A5",
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: ["#E5E5E7"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false,
|
||||||
|
areaStyle: {
|
||||||
|
color: ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
logAxis: {
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: "#aaaaaa",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
color: "#999999",
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: ["#e6e6e6"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false,
|
||||||
|
areaStyle: {
|
||||||
|
color: ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
timeAxis: {
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: "#aaaaaa",
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: "#333",
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: true,
|
||||||
|
color: "#9899A5",
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
type: "dashed",
|
||||||
|
color: ["#E5E5E7"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false,
|
||||||
|
areaStyle: {
|
||||||
|
color: ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
iconStyle: {
|
||||||
|
borderColor: "#999999",
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
iconStyle: {
|
||||||
|
borderColor: "#666666",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
left: "right",
|
||||||
|
top: "bottom",
|
||||||
|
textStyle: {
|
||||||
|
color: "#9899A5",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
axisPointer: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#8F84FF",
|
||||||
|
width: 1,
|
||||||
|
},
|
||||||
|
crossStyle: {
|
||||||
|
color: "#8F84FF",
|
||||||
|
width: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
timeline: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#893448",
|
||||||
|
width: 1,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: "#893448",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
controlStyle: {
|
||||||
|
color: "#893448",
|
||||||
|
borderColor: "#893448",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
checkpointStyle: {
|
||||||
|
color: "#eb8146",
|
||||||
|
borderColor: "#ffb248",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
color: "#ffb248",
|
||||||
|
},
|
||||||
|
controlStyle: {
|
||||||
|
color: "#893448",
|
||||||
|
borderColor: "#893448",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
color: "#893448",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
visualMap: {
|
||||||
|
color: [
|
||||||
|
"#893448",
|
||||||
|
"#d95850",
|
||||||
|
"#eb8146",
|
||||||
|
"#ffb248",
|
||||||
|
"#f2d643",
|
||||||
|
"rgb(247,238,173)",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
dataZoom: {
|
||||||
|
backgroundColor: "rgba(255,255,255,0)",
|
||||||
|
dataBackgroundColor: "rgba(255,178,72,0.5)",
|
||||||
|
fillerColor: "rgba(255,178,72,0.15)",
|
||||||
|
handleColor: "#ffb248",
|
||||||
|
handleSize: "100%",
|
||||||
|
textStyle: {
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
markPoint: {
|
||||||
|
label: {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
color: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -1,4 +1,5 @@
|
|||||||
import { utcParse } from "d3-time-format";
|
import { utcParse } from "d3-time-format";
|
||||||
|
import { round } from "lodash-es";
|
||||||
import type { Filter } from "@/types/filter";
|
import type { Filter } from "@/types/filter";
|
||||||
import { faSquareCheck } from "@fortawesome/free-regular-svg-icons";
|
import { faSquareCheck } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { faFont, faHashtag, faList } from "@fortawesome/free-solid-svg-icons";
|
import { faFont, faHashtag, faList } from "@fortawesome/free-solid-svg-icons";
|
||||||
@ -52,3 +53,7 @@ export function parseDateTime(dateTime: string) {
|
|||||||
}
|
}
|
||||||
return date.getTime();
|
return date.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function percent(currentValue: number, maxValue: number, precision = 2) {
|
||||||
|
return round((currentValue / maxValue) * 100, precision);
|
||||||
|
}
|
||||||
|
@ -31,5 +31,7 @@
|
|||||||
"switch-theme": "Switch theme",
|
"switch-theme": "Switch theme",
|
||||||
"system": "System",
|
"system": "System",
|
||||||
"tasks": "Tasks",
|
"tasks": "Tasks",
|
||||||
|
"total-free": "Total free",
|
||||||
|
"total-used": "Total used",
|
||||||
"vms": "VMs"
|
"vms": "VMs"
|
||||||
}
|
}
|
||||||
|
@ -31,5 +31,7 @@
|
|||||||
"switch-theme": "Changer de thème",
|
"switch-theme": "Changer de thème",
|
||||||
"system": "Système",
|
"system": "Système",
|
||||||
"tasks": "Tâches",
|
"tasks": "Tâches",
|
||||||
|
"total-free": "Total libre",
|
||||||
|
"total-used": "Total utilisé",
|
||||||
"vms": "VMs"
|
"vms": "VMs"
|
||||||
}
|
}
|
||||||
|
7
@xen-orchestra/lite/src/types/chart.ts
Normal file
7
@xen-orchestra/lite/src/types/chart.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export type LinearChartData = {
|
||||||
|
label: string;
|
||||||
|
data: {
|
||||||
|
date: string;
|
||||||
|
value: number;
|
||||||
|
}[];
|
||||||
|
}[];
|
3
@xen-orchestra/lite/src/types/human-format.d.ts
vendored
Normal file
3
@xen-orchestra/lite/src/types/human-format.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
declare module "human-format" {
|
||||||
|
function bytes(value: number): string;
|
||||||
|
}
|
38
yarn.lock
38
yarn.lock
@ -7961,6 +7961,14 @@ ecc-jsbn@~0.1.1:
|
|||||||
jsbn "~0.1.0"
|
jsbn "~0.1.0"
|
||||||
safer-buffer "^2.1.0"
|
safer-buffer "^2.1.0"
|
||||||
|
|
||||||
|
echarts@^5.3.3:
|
||||||
|
version "5.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.3.3.tgz#df97b09c4c0e2ffcdfb44acf518d50c50e0b838e"
|
||||||
|
integrity sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==
|
||||||
|
dependencies:
|
||||||
|
tslib "2.3.0"
|
||||||
|
zrender "5.3.2"
|
||||||
|
|
||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||||
@ -17166,6 +17174,11 @@ reselect@^2.5.4:
|
|||||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047"
|
resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047"
|
||||||
integrity sha512-KjVKPrNEDQ4nDuIFseuoNP3yp2lz8bipFlCjUkbD8WZTt2zTcJIfCDaSdOkGrChu9nKfWeXsljQQ2j4I5pcwaQ==
|
integrity sha512-KjVKPrNEDQ4nDuIFseuoNP3yp2lz8bipFlCjUkbD8WZTt2zTcJIfCDaSdOkGrChu9nKfWeXsljQQ2j4I5pcwaQ==
|
||||||
|
|
||||||
|
resize-detector@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/resize-detector/-/resize-detector-0.3.0.tgz#fe495112e184695500a8f51e0389f15774cb1cfc"
|
||||||
|
integrity sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==
|
||||||
|
|
||||||
resolve-cwd@^2.0.0:
|
resolve-cwd@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||||
@ -19068,6 +19081,11 @@ tsconfig-paths@^3.11.0, tsconfig-paths@^3.14.1:
|
|||||||
minimist "^1.2.6"
|
minimist "^1.2.6"
|
||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
|
tslib@2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||||
|
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||||
|
|
||||||
tslib@^1.11.1, tslib@^1.8.1:
|
tslib@^1.11.1, tslib@^1.8.1:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
@ -19771,6 +19789,19 @@ vue-demi@*:
|
|||||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.5.tgz#d5eddbc9eaefb89ce5995269d1fa6b0486312092"
|
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.5.tgz#d5eddbc9eaefb89ce5995269d1fa6b0486312092"
|
||||||
integrity sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==
|
integrity sha512-tO3K2bML3AwiHmVHeKCq6HLef2st4zBXIV5aEkoJl6HZ+gJWxWv2O8wLH8qrA3SX3lDoTDHNghLX1xZg83MXvw==
|
||||||
|
|
||||||
|
vue-demi@^0.13.2:
|
||||||
|
version "0.13.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.7.tgz#5ae380b15c13be556ac4a0da0a48450c98a01d4b"
|
||||||
|
integrity sha512-hbhlvpx1gFW3TB5HxJ0mNxyA9Jh5iQt409taOs6zkhpvfJ7YzLs1rsLufJmDsjH5PI1cOyfikY1fE/meyHfU5A==
|
||||||
|
|
||||||
|
vue-echarts@^6.2.3:
|
||||||
|
version "6.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-echarts/-/vue-echarts-6.2.3.tgz#77973c417a56bca76847576ab903ab92979d75bb"
|
||||||
|
integrity sha512-xHzUvgsgk/asJTcNa8iVVwoovZU3iEUHvmBa3bzbiP3Y6OMxM1YXsoWOKVmVVaUusGs4ob4pSwjwNy2FemAz9w==
|
||||||
|
dependencies:
|
||||||
|
resize-detector "^0.3.0"
|
||||||
|
vue-demi "^0.13.2"
|
||||||
|
|
||||||
vue-eslint-parser@^9.0.0, vue-eslint-parser@^9.0.1:
|
vue-eslint-parser@^9.0.0, vue-eslint-parser@^9.0.1:
|
||||||
version "9.0.3"
|
version "9.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz#0c17a89e0932cc94fa6a79f0726697e13bfe3c96"
|
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz#0c17a89e0932cc94fa6a79f0726697e13bfe3c96"
|
||||||
@ -20654,3 +20685,10 @@ zepto@^1.2.0:
|
|||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98"
|
resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98"
|
||||||
integrity sha512-C1x6lfvBICFTQIMgbt3JqMOno3VOtkWat/xEakLTOurskYIHPmzJrzd1e8BnmtdDVJlGuk5D+FxyCA8MPmkIyA==
|
integrity sha512-C1x6lfvBICFTQIMgbt3JqMOno3VOtkWat/xEakLTOurskYIHPmzJrzd1e8BnmtdDVJlGuk5D+FxyCA8MPmkIyA==
|
||||||
|
|
||||||
|
zrender@5.3.2:
|
||||||
|
version "5.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.3.2.tgz#f67b11d36d3d020d62411d3bb123eb1c93cccd69"
|
||||||
|
integrity sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==
|
||||||
|
dependencies:
|
||||||
|
tslib "2.3.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user